For this week’s looking outwards I looked at a project by Bogdan Soban, who uses random generative processes to create artwork. One example is Abstraction, done in 2005 by this random algorithm. I admire how every piece he makes with this process ends up looking completely different, in every way possible. The style and color palette are unique to each art piece. He uses Visual Basic to create the art, and uses a random number generator to calculate the seed start time for the generative process. I admire the algorithms he has created more than this specific piece, and am using it only as an example. He has created many different programs that create different style pieces, such as CREATOR, DISCOVERER, COLLAGE, and more. He even released these programs for free on his site, and below are two images showing the interfaces for two of these programs.
/*
Connor McGaffin
Section C
cmcgaffi@andrew.cmu.edu
Project-06
*/
function setup() {
createCanvas(480, 480);
}
//--------------------------
function draw() {
background(0, 100, 150);
angleMode(DEGREES);
noStroke();
// Fetch the current time
var H = hour();
var M = minute();
var S = second();
// Compute the widths of the rectangles
var mappedH = map(H, 0,23, 0,width);
var mappedM = map(M, 0,59, 0,width);
var mappedS = map(S, 0,59, 0,width / 2);
var rectHeight = height / 3;
var r = 350 //pizza radius
var x = width / 2;
var y = height / 2;
//pepperoni
var pr = 10
//background
//tray
fill(220);
ellipse(x, y, r + 35, r + 35);
fill(195);
ellipse(x, y, r + 20, r + 20);
//grease
strokeWeight(20);
stroke('rgba(120, 90, 0, 0.3)');
noFill();
ellipse(x, y, r - 100, r - 100);
ellipse(x, y, r - 90, r - 90);
strokeWeight(10);
ellipse(x, y, r - 35, r - 35);
ellipse(x, y, r - 180, r - 180);
fill('rgba(110, 100, 0, 0.3)');
ellipse(x, y, 50, 50);
//text
noStroke();
fill(195);
textAlign(CENTER);
text("when the moon hits your eye like a...", 107, 20);
text("...that's amore", width - 45, height - 15);
//HOURS
//cheese
fill(215,205,0);
arc(x, y, r, r, 0, H * (360 / 24));
//slices
for(var i = 0; i < H + 1; i++){
push();
translate(x, y);
rotate(15 * i); // 60 div by 24
stroke(210, 180, 0);
strokeWeight(2);
line(0, 0, r / 2, 0);
pop();
}
//crust
noFill();
strokeWeight(9);
stroke(140,80,0);
arc(x, y, r, r, 0, H * (360 / 24));
//MINUTES
//pepperoni
for(var i = 0; i < M + 1; i++){
push();
translate(x, y);
noStroke();
rotate(6 * i); // 60 div by 24
fill(150,0,0);
ellipse(0, 202, pr, pr);
pop();
}
//SECONDS
//olives
for(var i = 0; i < S + 1; i++){
push();
translate(x, y);
noFill();
strokeWeight(3);
stroke(0);
rotate(6 * i); // 60 div by 24
ellipse(0, 215, pr - 3, pr - 3);
pop();
}
//fill(100);
//rect(0, 1*rectHeight, mappedM, rectHeight);
//fill(150);
//rect(0, 2*rectHeight, mappedS, rectHeight);
/* Uncomment this block in order to
// Display numbers to indicate the time
fill(255);
text(H, 9, 0*rectHeight + 19);
text(M, 9, 1*rectHeight + 19);
text(S, 9, 2*rectHeight + 19);
*/
}
This post was incredibly satisfying to take in once completed. Beginning this project, I wanted to create a clock that operated with additive pizza slices at its core. When I was younger, I hated when my sister ordered olives because even if it was only on a portion of the pizza, it would cause the whole pie to smell like olives while in the box.
With this as a basic framework, I began to generate a pizza pie with a noticeable lack of olives actually on it. Instead, all of the olives are placed beyond its diameter, as they count the seconds. Pepperoni serves as a geometrically similar mediator for minutes, while the pie slices count the hours of the day.
Beneath the pizza is a ring of grease on the tray–a sign of pizza that is as perfectly unhealthy as it should be.
This simulation, created with Processing, utilizes randomness in simulating evolution. In each “generation,” 1000 creatures are created and the 500 that “walk” the furthest distance forward survive; new creatures are generated based on the survivors, and so on. I thought this was a fun and interesting application of randomness. Some of the early creatures are really derpy and funny, which is cute. But the really cool thing is seeing how much the creatures adapt after a couple of generations, and how certain “species” eventually dominate, ending up with one best optimized model. Since randomness is inherent in many parts of our everyday lives, it makes sense that randomness in computation, especially in experiments like this, can be very useful. I can see this type of prototyping being used in developing robot motion, finding the most aerodynamic shape for a plane, etc.
// Catherine Coyle
// ccoyle@andrew.cmu.edu
// Section C
// Project 6 - Abstract Clock
var notes = [];
var audience = [];
var mouthY = 120;
var dir = .3;
function setup() {
createCanvas(480, 480);
}
function draw() {
var H = hour() % 12;
var M = minute();
var S = second();
// this accounts for an off by 1 error that happens in the afternoon
if (hour() > 12) {
H = (hour() % 12) - 1;
}
// resetting the storage of notes/audience members every
// new minute/new hour
if (S == 0) {
notes = [];
}
if (M == 0) {
audience = [];
}
// the basic bg art of the clock is gonna be really complicated
// so to keep draw() from getting too messy im doing it
// in another function
drawBG();
// generating randomized notes
for(var i = 0; i < S; i++) {
// only add on one per draw call so its not
// generating a ton of notes every second
if (i == notes.length) {
notes.push([random(15,width-10), random(height / 2),
random(-3,3), random(-3,3), 1, 1]);
}
}
// do same thing for minutes
for(var i = 0; i < M; i++) {
if (i == audience.length) {
audience.push([random(20, width - 20), random(height / 2 + 80, height - 20)]);
}
}
// i want to draw the notes and have them float around!
for(var i = 0; i < notes.length; i++) {
// 0 is x, 1 is y, 2 is xvel, 3 is yvel, 4 is xdir, 5 ydir
notes[i][0] += notes[i][4] * notes[i][2];
if (notes[i][0] > width - 10 || notes[i][0] < 15) {
notes[i][4] = -1 * notes[i][4]
}
notes[i][1] += notes[i][5] * notes[i][3];
if (notes[i][1] > height / 2 + 20 || notes[i][1] < 0) {
notes[i][5] = -1 * notes[i][5];
}
// this whole thing is just basic movement stuff
// but it looks more complicated bc the values are stored in
// nested lists
drawNote(notes[i][0], notes[i][1]);
}
// partially hardcoding drawing locations for coffee cups (hours)
for(var i = 0; i <= H; i++) {
if (i < 3) {
drawCoffee(25 + i*45, height / 2 + 20);
}
if ((i >= 3) & (i < 5)) {
drawCoffee(50 + (i - 3) * 45, height / 2 - 23);
}
if (i == 5) {
drawCoffee(75 + (i - 5) * 45, height / 2 - 65);
}
if ((i > 5) & (i < 9)) {
drawCoffee(width - 10 - (i - 5) * 45, height / 2 + 20);
}
if ((i >= 9) & (i < 11)) {
drawCoffee(width - 35 - (i - 8) * 45, height / 2 - 23);
}
if (i == 11) {
drawCoffee(width - 105, height / 2 - 65);
}
}
// i want him to be in front of the music
drawKK();
// the audience (minutes) are randomized in front of him
for(var i = 0; i < audience.length; i++) {
drawAudience(audience[i][0], audience[i][1]);
}
// i want his mouth to move as he sings!
mouthY += dir;
if (mouthY > 128) {
dir = -dir;
}
if (mouthY < 120) {
dir = -dir;
}
// drawing the actual mouth
fill(0);
stroke(0);
strokeWeight(3);
line(width / 2, 105, width / 2, 115);
line(width / 2, 115, width / 2 + 10, 120);
line(width / 2, 115, width / 2 - 10, 120)
noStroke();
quad(width / 2 + 10, 120, width / 2, 115, width / 2 - 10, 120, width / 2, mouthY);
// i want him to blink too
drawEyes(S);
drawSpotlight();
}
// everything below here is less coding magic and
// more magic numbers for graphics
function drawBG() {
noStroke();
background(193, 120, 51);
// platform top
fill(197, 155, 113);
rect(0, height / 2 + 40, width, 200);
// platform front
fill(132, 62, 11);
rect(0, height / 2 + 70, width, 200);
}
function drawKK() {
// stool legs
fill(209, 175, 66);
rect(width / 2 - 60, height / 2, 20, 60);
rect(width / 2 + 40, height / 2, 20, 60);
fill(201, 146, 58); // back leg
rect(width / 2 - 10, height / 2, 20, 45);
// stool
fill(201, 146, 58); // stool shadow
ellipse(width / 2, height / 2 + 3, 150, 38);
fill(209, 175, 66); // this is the main stool color
ellipse(width / 2, height / 2, 150, 30);
// kk body
fill(255);
ellipse(width / 2, 180, 90, 120)
fill(247, 242, 234); // kk shadow color
ellipse(width / 2, 110, 68, 68);
// kks head
fill(255);
ellipse(width / 2, 75, 90, 90);
ellipse(width / 2, 100, 70, 70);
// eyebrowsss
fill(0);
ellipse(width / 2 + 22, 65, 23, 25);
ellipse(width / 2 - 22, 65, 23, 25);
fill(255);
ellipse(width / 2 + 22, 70, 24, 15);
ellipse(width / 2 - 22, 70, 24, 15);
// ears
noStroke();
fill(255);
triangle(width / 2 + 40, 40, width / 2 + 60, 40, width / 2 + 57.5, 70);
triangle(width / 2 - 40, 40, width / 2 - 60, 40, width / 2 - 57.5, 70);
// right leg
ellipse(width / 2 + 25, height / 2 - 10, 35, 100);
fill(247, 242, 234);
ellipse(width / 2 + 30, height / 2 + 40, 30, 30);
fill(255);
ellipse(width / 2 + 30, height / 2 + 35, 30, 30);
//left leg
fill(255);
ellipse(width / 2 - 15, height / 2 - 5, 70, 35);
fill(247, 242, 234);
ellipse(width / 2 + 18, height / 2, 20, 28);
fill(255);
ellipse(width / 2 + 15, height / 2, 20, 30);
// guitar neck
fill(160, 109, 27);
rect(width / 2, height / 2 - 60, 130, 20);
fill(102, 69, 17);
rect(width / 2 + 120, height / 2 - 62.5, 30, 25);
fill(183, 177, 167); // little knobs at the end
ellipse(width / 2 + 125, height / 2 - 65, 4, 4);
ellipse(width / 2 + 135, height / 2 - 65, 4, 4);
ellipse(width / 2 + 145, height / 2 - 65, 4, 4);
ellipse(width / 2 + 125, height / 2 - 35, 4, 4);
ellipse(width / 2 + 135, height / 2 - 35, 4, 4);
ellipse(width / 2 + 145, height / 2 - 35, 4, 4);
// guitar body
fill(209, 175, 6);
beginShape();
curveVertex(192, 220);
curveVertex(181, 188);
curveVertex(187, 160);
curveVertex(199, 153);
curveVertex(221, 156);
curveVertex(234, 163);
curveVertex(247, 162);
curveVertex(256, 160);
curveVertex(267, 167);
curveVertex(277, 188);
curveVertex(277, 205);
curveVertex(268, 213);
curveVertex(254, 214);
curveVertex(239, 213);
curveVertex(228, 217);
curveVertex(210, 221);
curveVertex(185, 211);
curveVertex(181, 188);
curveVertex(183, 173);
endShape();
// guitar details
fill(175, 123, 40); // background thing
ellipse(width / 2 + 3, height / 2 - 45, 30, 20);
fill(102, 69, 17); // hole
ellipse(width / 2 + 10, height / 2 - 52, 25, 25);
ellipse(width / 2 - 30, height / 2 - 52, 10, 25);
// kks hands
fill(255);
ellipse(width / 2 - 55, height / 2 - 75, 30, 30);
ellipse(width / 2 + 70, height / 2 - 35, 30, 30);
}
function drawCoffee(x, y) {
// mug
noStroke();
fill(255);
rect(x, y, 30, 40);
ellipse(x + 15, y, 30, 5);
ellipse(x + 15, y + 40, 30, 5);
// handle
stroke(255);
strokeWeight(5);
noFill();
ellipse(x, y + 20, 20, 20);
// coffee
noStroke();
fill(132, 62, 11);
ellipse(x + 15, y, 25, 2);
}
// will draw music note at given coords
function drawNote(x, y) {
fill(0);
stroke(0);
strokeWeight(5);
line(x, y, x, y + 20);
noStroke();
ellipse(x - 5, y + 20, 15, 10);
triangle(x, y-2.25, x, y + 5.75, x + 12, y + 1.75);
}
// will draw audience member at coords
function drawAudience(x, y) {
noStroke();
fill(239, 239, 208);
ellipse(x, y-1, 48, 50);
fill(48, 49, 51);
ellipse(x, y, 50, 50);
fill(0);
ellipse(x, y + 3, 46, 46);
}
function drawEyes(S) {
if (S % 5 == 0) {
fill(0);
ellipse(width / 2, 105, 15, 10);
strokeWeight(3);
stroke(0);
noFill();
beginShape();
curveVertex(width / 2 + 11, 85);
curveVertex(width / 2 + 11, 85);
curveVertex(width / 2 + 22, 88);
curveVertex(width / 2 + 34, 85);
curveVertex(width / 2 + 34, 85);
endShape();
beginShape();
curveVertex(width / 2 - 11, 85);
curveVertex(width / 2 - 11, 85);
curveVertex(width / 2 - 22, 88);
curveVertex(width / 2 - 34, 85);
curveVertex(width / 2 - 34, 85);
endShape();
} else {
// eyes and nose
fill(0);
ellipse(width / 2 + 22, 75, 15, 15);
ellipse(width / 2 - 22, 75, 15, 15);
ellipse(width / 2, 105, 15, 10);
//eyelids
strokeWeight(3);
stroke(0);
beginShape();
curveVertex(width / 2 + 11, 71);
curveVertex(width / 2 + 11, 71);
curveVertex(width / 2 + 22, 68);
curveVertex(width / 2 + 34, 71);
curveVertex(width / 2 + 34, 71);
endShape();
beginShape();
curveVertex(width / 2 - 11, 71);
curveVertex(width / 2 - 11, 71);
curveVertex(width / 2 - 22, 68);
curveVertex(width / 2 - 34, 71);
curveVertex(width / 2 - 34, 71);
endShape();
}
}
function drawSpotlight() {
noStroke();
fill(0, 0, 0, 30);
quad(0, 0, width / 2 - 70, 0, width / 2 - 150, height / 2 + 70, 0, height / 2 + 70);
quad(width, 0, width / 2 + 70, 0, width / 2 + 150, height / 2 + 70, width, height / 2 + 70);
rect(0, height / 2 + 70, width, 200);
}
I simultaneously had a really fun time with this project while I’m also extremely happy I’m finished.
Anyone who’s played the Nintendo game Animal Crossing will recognize this character as KK Slider. Animal Crossing has always been one of my favorite series, and I thought that it was fitting to do a project related to it for this assignment because the game plays in real time as well.
The musical notes represent seconds, audience members minutes, and coffee mugs hours.
I had a lot more trouble with this than I expected too. I got stuck on more than a few off by one errors, and its probably the most graphically complex project I’ve made for this class so far. I had a really hard time with plotting out the acoustic guitar (it’s still a bit lopsided but much better now). I ended up writing a program that would let me click on the screen where I wanted to place my dots and then would print the array of coordinates. It also removed the most recent coordinate when you clicked a key because it was very easy to mess up, and I didn’t want to have to start over entirely.
Altogether this project was fun and I’m really proud of what I made! (My code is super long so I’m crossing my fingers for no missed style errors.)
/*Sharon Yang
Section C
junginny
Project-06
*/
function setup() {
createCanvas(640, 480);
}
function draw() {
//fetch time
var H = hour();
var M = minute();
var S = second();
background(182,211,232);
angleMode(DEGREES);
//ground
fill(109,67,48);
noStroke();
rect(0,455,640,480);
//rain drops for seconds
strokeWeight(2);
stroke(255);
var rainSpeed;
rainSpeed = 0;
frameRate(1);
for (var i = 0; i <= S; i++) {
push();
translate(random(10,width-10),rainSpeed);
line(0,rainSpeed,0,rainSpeed+30);
rainSpeed+=15;
pop();
}
//plants for minutes
var amountMap; //number of plants = minutes
var plantY;
fill(97,120,50);
if (M == 1) {
strokeWeight(2);
stroke(97,120,50);
push();
translate(width/2,height-25);
plantY = random(-20,-60);
line(0,0,0,plantY);
noStroke();
ellipse(-5,plantY,10,5);
ellipse(5,plantY,10,5);
pop();
}
else {
for (var amount = 1; amount <= M; amount++) {
amountMap = map(amount-1,0,M-1,15,width-25);
strokeWeight(2);
stroke(97,120,50);
push();
translate(0,height-25);
plantY = random(-20,-60);
line(amountMap,0,amountMap,plantY);
noStroke();
ellipse(amountMap-5,plantY,10,5);
ellipse(amountMap+5,plantY,10,5);
pop();
}
}
//petals on the flower for hours
if (H > 12) { //0~12 hours
H = H % 12
}
stroke(97,120,50);
strokeWeight(4);
line(320,230,320,455);
noStroke();
fill(242,155,174);
for (var i = 0; i < H; i++) {
push();
translate(320,220);
rotate(i * 30);
ellipse(0,-25,15,60);
pop();
}
noStroke();
fill(175,23,104);
ellipse(320,220,40,40);//bigger flower center
fill(95,40,100);
ellipse(320,220,25,25);//smaller flower center
}
For this project, I wanted to incorporate graphics with the clock function, and so I decided to make a flower to indicate the hours, the plants to indicate the minutes and the raindrops to indicate the seconds. I encountered several challenges including placing the plants without them overlapping as their number increases each minute. I resolved that my using the map function. The rotation and translation of the flower petals was also quite difficult but it became more simple once I converted the time to 12 hours instead of 24 hours.
//Justin Yook
//jyook@andrew.cmu.edu
//Section C
//Project 06
var prevSec;
var millisRolloverTime;
var sizeS = []; // stores sizes for each seconds raindrop drawn
var xS = []; // stores x coordinates for seconds raindrop
var yS = []; // stores y coordinates for seconds raindrop
var sizeM = 0; // starting size of minute raindrop
var sizeH = 0; // starting sizse of hour raindrop
function setup() {
createCanvas(300, 300);
background(164, 194, 205);
}
function draw() {
var S = second(); // keeps track of each second
var M = 0; // keeps track of each minute
var H = 0; // keeps track of each hour
// make sure that the second matches up properly with milliseconds passed
if (prevSec != S) {
millisRolloverTime = millis();
}
prevSec = S;
var mils = floor(millis() - millisRolloverTime);
// i represents current seconds raindrop
for (var i = 0; i < S; i++) {
var rxS = random(0, 300); // random x location of seconds raindrop
var ryS = random(0, 300); // random y location of seconds raindrop
xS.push(rxS); // append random x location of seconds raindrop to xS array
yS.push(ryS); // append random y location of seconds raindrop to yS array
var osizeS = 0; // all raindrops have size of 0 before expanding
sizeS.push(osizeS); // append size of seconds raindrop to sizeS array
fill(75, 105, 125, 200);
noStroke();
ellipse(xS[i], yS[i], sizeS[i], sizeS[i]);
sizeS[i] += 1;
// limit size of second raindrop size
if (sizeS[i] > 40) {
sizeS[i] = 40;
fill(164, 194, 205);
rect(0, 0, width, height);
}
// if second() reaches 59 seconds
if (S % 59 == 0) {
sizeS = [];
xS = [];
yS = [];
M += 1;
// draw minute raindrop
fill(75, 105, 125, 200);
ellipse(width/2, height/2, sizeM, sizeM);
sizeM += 1;
// limit size of minute raindrop
if (sizeM > 80) {
sizeM = 80;
}
// if M reaches 59 minutes
if (M % 59 == 0) {
// draw hour raindrop
fill(75, 105, 125, 200);
ellipse(width/2, height/2, sizeH, sizeH);
sizeH += 1;
// limit size of hour raindrop
if (sizeH > 120) {
sizeH = 120;
}
}
}
}
}
For this project, I tried to imitate raindrops falling into a pond. Every second, a small raindrop falls. And once it is one minute, a bigger raindrop appears. The hour raindrop follows the same idea. This project was the most difficult by far in my opinion, because I had to fully understand arrays to utilize it properly.
For this project, I was initially planning to just have a simple square with overlaid colors, but while writing that code, I was reminded of old tvs, especially those with glitched screens:
I was inspired by that idea, so I sketched up a tv in Illustrator, put it into p5, and then modified my code so that the colors would fit to the screen.
The color layers are red, blue, and green (RBG) under the blend mode “difference,” so as they overlap and interact with each other, the screen’s color palette changes. The colors on the screen do not change only by the minute, but also by the time of day (based on the position of the hours, minutes, and seconds layers in relationship to each other).
/* Alexandra Kaplan
aekaplan@andrew.cmu.edu
Section C
Project - 06
*/
var dropY = 100;
var dropX = 150
var xarray = [110];
var yarray = [105];
function setup() {
createCanvas(400, 300);
frameRate(30); //each second is 30 frames
}
function draw() {
background(230, 250, 255);
var H = hour(); // current hour
var M = minute(); // current minute
var S = second(); // current second
var milli = second(); //current millisecond
var HWaterHeight = map(M, 0, 59, 0, height); // chages the height of the water according to the minute
var waterColorb = map(H, 0, 23, 255, 120); // water changes from blue to grey over 24 hours
var dropW = map(S, 0, 59, 25, 5); // water drops gets smaller as gets closer to a minute
// draw water level
strokeWeight(0);
fill(150, 170, waterColorb); // water changes from blue to grey over 24 hours
rect(0, height - HWaterHeight, width, HWaterHeight);
//draw water drops
fill(170, 200, 225);
for(var i = 0; i < yarray.length; i++){ // draws water drop falling
ellipse(xarray[i], yarray[i], dropW, 20);
yarray[i] += 5;
}
if(frameCount % 30 === 0){ // every second a new drop is drawn
yarray.push(105);
xarray.push(random(110, 140)) // randomizes x position of water droplets
}
faucet(); // draws faucet
}
function faucet(x, y){
stroke(100);
fill(120);
rect(100, 80, 50, 35, 0, 0, 5, 5);
rect(0, 40, 150, 50, 0, 10, 0, 0);
stroke(160);
strokeWeight(1);
line(101, 113, 149, 109);
line(100, 108, 149, 104);
line(100, 103, 149, 99);
line(100, 98, 149, 94);
}
For this project, I took inspiration from a leaky faucet. It keeps track of time by dripping once per second, the water goes from the bottom to the top every hour, and the color of the water changes from blue to green-brown throughout a 24 hour time period. It was definitely a more difficult project than I originally anticipated, as I had to draw on and combine a lot of concepts we have learned throughout the class. The part that I had the most trouble with was getting a new drop to drip at every second.
Isohedral III by Tyler Hobbs is one of his many algorithmic computational art that uses the concept of randomness. In contrast to his other art, I think Isohedral III is most interesting because it is clear on how he uses randomness of shapes, patterns, and colors. For example, one can see how all the shapes such as spirals, circles, and radial lines have repetitions, but when they are put together in random ways, they create random tile shapes throughout. Unfortunately, Hobbs does not share his source code to the public. His artistic sensibilities are shown from his color arrangement; the way the overall color scheme changes from blue, to red, to green is eye popping, and complement each other very well.
// Joanne Lee
// Section C
// joannele@andrew.cmu.edu
// Project-06
var skyR = 135;
var skyG = 206;
var skyB = 235;
var grassR = 206;
var grassG = 229;
var grassB = 178;
function setup() {
createCanvas(375,480);
}
function draw() {
// hour hand -- represented by background colors // 12 hr clock
var h = hour() % 12;
noStroke();
background(skyR - 10 * h, skyG - 20 * h, skyB - 20 * h); // sky --> darkens every 12 hours
fill(grassR - 30 * h, grassG - 50 * h, grassB - 20 * h, 99); // darkens every 12 hours
triangle(0, height * 0.75, 0, height, 1500, height); // plain 1
triangle(width, height * 0.55, width, height, -1500, height); // plain 2
// minute hand -- represented by the sun position
var m = minute() / 60;
push();
noStroke();
if (m < 0.25 || m > 0.75) { // make opaque when not in sky
fill(255, 200, 100, 50);
}
else {
fill(255, 200, 100);
}
translate(width / 2, height / 2);
rotate(radians(m * 360));
ellipse(0, 200, 60, 60);
pop();
// second hand -- represented by the clouds
var s = second() / 60;
var x1 = -80; // x-values to keep cloud off screen, keeping continuous movement
var x2 = -120;
var x3 = -40;
var shift = (width+160) * s; // move across screen proportionally
push();
noStroke();
fill(255);
ellipse(x1 + shift, 110, 120, 65);
ellipse(x2 + shift, 110, 90, 45);
ellipse(x3 + shift, 116, 100, 40);
pop();
}
Going into the project, I knew I wanted to make use of background color changes as well as real elements on the screen moving (i.e. cloud, sun).
The hour hand is denoted by the change in sky / grass color. Over the progression of 12 hours, the sky and grass becomes darker in color. I chose to do a 12 hour clock because I wanted the hour hand differences to be more apparent. The minute hand is denoted by the position of the sun. As you can see in my sketch below, I originally intended for the sun to go off screen, but I wanted it to be more clear what the current minutes were. Therefore, I decided to keep it on the screen and make it more opaque as to not draw too much attention through the grass. And finally, the seconds are denoted by the pace of the cloud moving across the screen in what appears to be a continuous loop. I personally found this project to be one of the most interesting projects to work on so far.