farcar – Clock

Carnegie Clock                           

Sketches                         

Screenshots                         

Feb 04, 10:38:51

Feb 06, 20:55:52

Feb 06, 19:37:49

Jul 12, 12:41,17

Apr 26, 12:43:15

Nov 26, 11:20:36

Feb 12, 23:29:26

Description                          

Carnegie Clock is the fun new way to bring the time to Carnegie Mellon Students. Stationed on the lawns in front of The Fence facing Hunt Library, Carnegie Clock tells the time through the CMU campus. Rooms lit on the Right Wing of Hunt tell the seconds, rooms on the Left Wing tell the minutes, and the number of people on campus tell the time (military time). In the daytime, the sun is out and rotating above, and at night, the moon is out. Once the time goes from 23:59:59 to 0:00:00, no one is on campus anymore: everyone has gone back to their dorms. The Fence is repainted a different color each night, with a different date painted on it each time. Each season, there is a new background to be seen. In winter, the students wear coats and scarves. Brrr! Better yet, the students in the clock complain like real CMU students! They have an array of quotes to say that is different every season.

The creation of this clock was made possible through vectoring all the shapes in Illustrator. P5.js was used to time certain elements to the clock and move images around. For code, see below or on the code tab of Open Processing above for better readability.

Code                          
Index Tab

var humans = [];
var humanList = [];
var scarves = [];
var winQuotes = [];
var sprQuotes = [];
var sumQuotes = [];
var fallQuotes = [];
var curQuotes = [];
var fences = [];
var season = [];
var nums = [];
var letters = [];
var months = [];
var space, reset;
var curFence, curSeason;
var sidewalk, hunt, morning, night, dayNight, sun, moon, light, noLight;
 
 
function preload() {
	for(var i = 1; i < 6; i++)
		append(humanList, createVector(loadImage("Human0"+i+"_L.png"),loadImage("Human0"+i+"_R.png")));
	for(var h = 1; h < 6; h++)
		append(scarves, loadImage("Scarf0"+h+".png"));
	for(var j = 1; j < 5; j++)
		append(fences, loadImage("Fence0"+j+".png"));
	append(season, createVector(loadImage("WinterStreet.png"),loadImage("WinterHunt.png")));
	append(season, createVector(loadImage("SpringStreet.png"),loadImage("SpringHunt.png")));
	append(season, createVector(loadImage("SummerStreet.png"),loadImage("SummerHunt.png")));
	append(season, createVector(loadImage("FallStreet.png"),loadImage("FallHunt.png")));
	letters['A'] = loadImage("A.png");
	letters['B'] = loadImage("B.png");
	letters['C'] = loadImage("C.png");
	letters['D'] = loadImage("D.png");
	letters['E'] = loadImage("E.png");
	letters['F'] = loadImage("F.png");
	letters['G'] = loadImage("G.png");
	letters['H'] = loadImage("H.png");
	letters['I'] = loadImage("I.png");
	letters['J'] = loadImage("J.png");
	letters['K'] = loadImage("K.png");
	letters['L'] = loadImage("L.png");
	letters['M'] = loadImage("M.png");
	letters['N'] = loadImage("N.png");
	letters['O'] = loadImage("O.png");
	letters['P'] = loadImage("P.png");
	letters['Q'] = loadImage("Q.png");
	letters['R'] = loadImage("R.png");
	letters['S'] = loadImage("S.png");
	letters['T'] = loadImage("T.png");
	letters['U'] = loadImage("U.png");
	letters['V'] = loadImage("V.png");
	letters['W'] = loadImage("W.png");
	letters['X'] = loadImage("X.png");
	letters['Y'] = loadImage("Y.png");
	letters['Z'] = loadImage("Z.png");
	letters['.'] = loadImage("Dot.png");
	letters[0] = loadImage("0.png");
	letters[1] = loadImage("1.png");
	letters[2] = loadImage("2.png");
	letters[3] = loadImage("3.png");
	letters[4] = loadImage("4.png");
	letters[5] = loadImage("5.png");
	letters[6] = loadImage("6.png");
	letters[7] = loadImage("7.png");
	letters[8] = loadImage("8.png");
	letters[9] = loadImage("9.png");
	append(months,createVector('J','A','N'));
	append(months,createVector('F','E','B'));
	append(months,createVector('M','A','R'));
	append(months,createVector('A','P','R'));
	append(months,createVector('M','A','Y'));
	append(months,createVector('J','U','N'));
	append(months,createVector('J','U','L'));
	append(months,createVector('A','U','G'));
	append(months,createVector('S','E','P'));
	append(months,createVector('O','C','T'));
	append(months,createVector('N','O','V'));
	append(months,createVector('D','E','C'));
	morning = loadImage("DaySky.png");
	night = loadImage("NightSky.png");
	dayNight = loadImage("DayNightSky.png");
	sun = loadImage("Sun.png");
	moon = loadImage("Moon.png");
	light = loadImage("Light.png");
	noLight = loadImage("NoLight.png");
}
 
function setup() {
	createCanvas(800, 500);
	append(nums,[1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1]);
	append(nums,[0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1]);
	append(nums,[1,1,1,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,1,1,1]);
	append(nums,[1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,0,0,1,1,1,1,1]);
	append(nums,[1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1]);
	append(nums,[1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,1,1,1,1,1]);
	append(nums,[1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1]);
	append(nums,[1,1,1,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0]);
	append(nums,[1,1,1,1,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,1,1,1,1]);
	append(nums,[1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1]);
	append(winQuotes, "Brrr, it's cold.");
	append(winQuotes, "Should have brought more to wear.");
	append(winQuotes, "Look at all this snow.");
	append(winQuotes, "It's slippery.");
	append(winQuotes, "Rush Shatz.");
	append(winQuotes, "Time for 112 lecture.");
	append(winQuotes, "Winter semester sucks.");
	append(winQuotes, "I'm getting dry skin.");
	append(winQuotes, "I'm failing my classes.");
	append(winQuotes, "Chipotle is my life.");
	append(winQuotes, "There's no good sushi on campus.");
	append(winQuotes, "Oh, the weather outside is frightful.");
	append(winQuotes, "So dark so early.");
	append(sprQuotes, "Look at all the flowers.");
	append(sprQuotes, "I can finally breathe.");
	append(sprQuotes, "Who cuts this grass?.");
	append(sprQuotes, "Where are the flowers?.");
	append(sprQuotes, "Take a picture with me.");
	append(sprQuotes, "Semester's almost over.");
	append(sprQuotes, "Anyone wanna go for milkshakes?");
	append(sprQuotes, "I'm running out of DineX.");
	append(sprQuotes, "It's getting warmer.");
	append(sprQuotes, "SPRING CARNIVAL!!");
	append(sumQuotes, "SO HOT!!");
	append(sumQuotes, "Why am I spending my summer here?");
	append(sumQuotes, "Where is the closest beach?");
	append(sumQuotes, "I need new clothes.");
	append(sumQuotes, "Everywhere is closed.");
	append(sumQuotes, "It's really humid.");
	append(sumQuotes, "Anyone have water?");
	append(sumQuotes, "Let's see a movie.");
	append(sumQuotes, "Classes during summer?");
	append(sumQuotes, "Such long days.");
	append(fallQuotes, "Back here again.");
	append(fallQuotes, "Goodbye summer.");
	append(fallQuotes, "Keep stepping in leaves.");
	append(fallQuotes, "Where did all these leaves come from?");
	append(fallQuotes, "This is my worst semester yet.");
	append(fallQuotes, "Frat party tonight!");
	append(fallQuotes, "I need more sleep.");
	append(fallQuotes, "Why are morning classes a thing?");
	append(fallQuotes, "Anyone want to go to Craig Street?");
	append(fallQuotes, "Let's go to the new Tepper Quad.");
	append(fallQuotes, "Light semester.");
	append(fallQuotes, "Shatz hasn't changed.");
	for(var i = 0; i < 24; i++)
		curQuotes[i] = createVector("",0,0);
  imageMode(CENTER);
	rectMode(CENTER);
	textAlign(CENTER);
	textFont('Helvetica');
	textStyle(BOLD);
	curFence = fences[(day())%(fences.length)];
	frameRate(12);
	space = true;
	reset = false;
	noStroke();
	fill(0,50);
}
 
function draw() {
	background(100);
	set_background();
	set_season();
	set_sun();
	image(hunt,width/2+10,height/2+10);
	lights();
	set_fence();
	image(sidewalk,sidewalk.width/2,height-(sidewalk.height/2));
	add_humans();
	human_draw();
	darken();
	if(mouseIsPressed)
		display_stats();
	else if(reset)
		display_stats();
	else {
		textSize(13);
		fill(0);
		text("Click & Hold to display stats",95,height-7);
	}
}

Setting Tab

/*
-----------------Doccumentation-----------------
 
function set_background()
- sets background to night or day
 
function darken()
- darkens screen at night
 
function set_fence()
- changes fence by day
 
function set_season()
- sets the season for hunt & sidewalk
 
function set_sun()
- draws the sun/moon
 
function lights()
- displays minutes & seconds by lights on hunt
-------------------------------------------------
*/
 
 
//sets background to night or day
function set_background() {
	var hr = hour(); 
	if(hr < 6 || hr > 21)
		image(night,night.width/2,night.height/2);
	else if(hr >= 9 && hr < 18)
		image(morning,morning.width/2,morning.height/2);
	else
		image(dayNight,dayNight.width/2,dayNight.height/2);
}
 
 
//darkens screen at night
function darken() {
	var hr = hour();
	fill(0,75);
	if(hr < 6 || hr > 21)
		rect(width/2,height/2,width,height);
	else if((hr >= 6 && hr <= 9) || (hr >= 18 && hr <= 21)) {
		fill(0,50);
		rect(width/2,height/2,width,height);
		fill(0,75);
	}
}
 
 
//changes fence by day
function set_fence() {
	var today = day();
	curFence = fences[(today)%(fences.length)];
	image(curFence,curFence.width/2+17,height-(curFence.height/2)-70);
	var mon = month();
	var curMonth = months[mon-1];
	image(letters[curMonth.x],40,365);
	image(letters[curMonth.y],184,365);
	image(letters[curMonth.z],328,365);
	image(letters['.'],472,365);
	if(today < 10) {
		image(letters[0],616,365);
		image(letters[today],760,365);
	}
	else {
		image(letters[int(today/10)],616,365);
		image(letters[today%10],760,365);
	}
}
 
 
//sets the season for hunt & sidewalk
function set_season() {
	var mon = month();
	var i = 0;
	if(mon == 12 || mon < 3) {
		i = 0
		curSeason = "win";
	}
	else if(mon >= 3 && mon < 6) {
		i = 1;
		curSeason = "spr";
	}
	else if(mon >= 9 && mon < 12) {
		i = 3;
		curSeason = "fall";
	}
	else {
		i = 2;
		curSeason = "sum";
	}
	sidewalk = season[i].x;
	hunt = season[i].y;
}
 
 
//draws the sun/moon
function set_sun() {
	var hr = hour();
	var min = minute();
	if(hr >= 9 && hr < 18) {
		var sum = 60*hr + min;
		var t = map(sum,540,1140,0,PI);
		image(sun, width/2-(width*cos(t))/1.75, height/2-(height*sin(t))/2);
	}
	else if(hr < 6 || hr > 21) {
		var sum = 60*hr + min;
		if(hr > 21)
			var t = map(sum,1260,1440,0,1/3*PI);
		else
			var t = map(sum,0,360,1/3*PI,2/3*PI);
		image(moon, width/2-(width*cos(t))/1.75, height/2-(height*sin(t))/2);
	}
}
 
 
//displays minutes & seconds by lights on hunt
function lights() {
	var min = minute();
	if(min >= 10)
		var min1 = int(min/10);
	else
		var min1 = 0;
	var min2 = min%10;
	var sec = second();
	if(sec >= 10)
		var sec1 = int(sec/10);
	else
		var sec1 = 0;
	var sec2 = sec%10;
	for(var i = 0; i < 8; i++) {
		for(var j = 0; j < 4; j++) {
			//1st digit minute
			if(nums[min1][(4*i)+j]==1)
				image(light,179+30.15*j,115+35.3*i);
			else
				image(noLight,179+30.15*j,115+35.3*i);
			//2nd digit minute
			if(nums[min2][(4*i)+j]==1)
				image(light,299.6+30.15*j,115+35.3*i);
			else
				image(noLight,299.6+30.15*j,115+35.3*i);
			//1st digit second
			if(nums[sec1][(4*i)+j]==1)
				image(light,420.2+30.15*j,115+35.3*i);
			else
				image(noLight,420.2+30.15*j,115+35.3*i);
			//2nd digit second
			if(nums[sec2][(4*i)+j]==1)
				image(light,540.8+30.15*j,115+35.3*i);
			else
				image(noLight,540.8+30.15*j,115+35.3*i);
		}
	}
}

Human Tab

/*
-----------------Doccumentation-----------------
 
function human()
- human object constructor
 
function add_humans()
- adds human at regular intervals
 
function human_draw()
- draws all humans in array
 
function update_human(i)
- updates humans[i]
 
function human_quotes()
- prints out human quotes
 
-------------------------------------------------
*/
 
 
//human object constructor
function human() {
	var rand = random(0,1);
	if(rand < 0.5) {
		this.dir = 15*(rand+0.5);
		this.hum = humanList[int(random(0,humanList.length))].y;
		this.x = -(this.hum).width/2;
	}
	else {
		this.dir = -15*rand;
		this.hum = humanList[int(random(0,humanList.length))].x;
		this.x = width+(this.hum).width/2;
	}
	var rand2 = random(0,1);
	if(rand2 < 0.5) {
		this.y = height-(this.hum).height/2;
		this.top = true;
	}
	else {
		this.y = height-(this.hum).height/2;
		this.top = false;
	}
	this.scarf = scarves[int(random(0,scarves.length))];
}
 
 
//adds human at regular intervals
function add_humans(){
	if(humans.length < hour() && int(random(0,10)) == int(random(0,10)) && space)
	{
		append(humans, new human());
		space = false;
	}
	if(frameCount%5==0)
		space = true;
	if(humans.length > hour())
		humans = [];
}
 
 
//draws all humans in array
function human_draw() {
	for(var i = 0; i < humans.length; i++) {
		if(!(humans[i].top)) {
			image(humans[i].hum,humans[i].x,humans[i].y-50);
			if(curSeason == "win") {
				if(humans[i].dir > 0)
					image(humans[i].scarf,humans[i].x+9,humans[i].y-38);
				else
					image(humans[i].scarf,humans[i].x-9,humans[i].y-36);
			}
			if(random(0,1) >= 0.998) {
				if(curSeason == "win")
					curQuotes[i] = createVector(winQuotes[int(random(winQuotes.length))],random(150,250),0);
				else if(curSeason == "spr")
					curQuotes[i] = createVector(sprQuotes[int(random(sprQuotes.length))],random(150,250),0);
				else if(curSeason == "fall")
					curQuotes[i] = createVector(fallQuotes[int(random(fallQuotes.length))],random(150,250),0);
				else
					curQuotes[i] = createVector(sumQuotes[int(random(sumQuotes.length))],random(150,250),0);
			}
		}
	}
	for(var i = 0; i < humans.length; i++) {
		if(humans[i].top) {
			image(humans[i].hum,humans[i].x,humans[i].y-35);
			if(curSeason == "win") {
				if(humans[i].dir > 0)
					image(humans[i].scarf,humans[i].x+9,humans[i].y-23);
				else
					image(humans[i].scarf,humans[i].x-9,humans[i].y-21);
			}
			if(random(0,1) >= 0.998)
				if(curSeason == "win")
					curQuotes[i] = createVector(winQuotes[int(random(winQuotes.length))],random(150,250),0);
				else if(curSeason == "spr")
					curQuotes[i] = createVector(sprQuotes[int(random(sprQuotes.length))],random(150,250),0);
				else if(curSeason == "fall")
					curQuotes[i] = createVector(fallQuotes[int(random(fallQuotes.length))],random(150,250),0);
				else
					curQuotes[i] = createVector(sumQuotes[int(random(sumQuotes.length))],random(150,250),0);
		}
	}
	human_quotes();
	update_human();
}
 
 
//updates humans
function update_human() {
	for(var i = 0; i < humans.length; i++) {
		humans[i].x += humans[i].dir;
		if(humans[i].x > width+(humans[i].hum).width/2 || humans[i].x < -(humans[i].hum).width/2)
			humans[i] = new human();
		if(humans[i].y == height-(humans[i].hum).height/2)
			humans[i].y -= 10;
		else
			humans[i].y += 10;
	}
}
 
 
//prints out human quotes
function human_quotes() {
	var hr = hour();
	for(var i = 0; i < curQuotes.length; i++) {
		if(!(curQuotes[i].x == "")) {
			textSize(20);
			if(hr >= 9 && hr < 18)
				fill(255);
			else
				fill(0);
			text(curQuotes[i].x, humans[i].x - 50+0.75, humans[i].y - curQuotes[i].y+0.75);
			if(hr >= 9 && hr < 18)
				fill(0);
			else
				fill(255);
			text(curQuotes[i].x, humans[i].x - 50, humans[i].y - curQuotes[i].y);
			if(hr >= 9 && hr < 18)
				stroke(0);
			else
				stroke(255);
			if(humans[i].dir > 0)
				line(humans[i].x+10, humans[i].y-125, humans[i].x - 40, humans[i].y - curQuotes[i].y + 10);
			else
				line(humans[i].x-15, humans[i].y-125, humans[i].x - 40, humans[i].y - curQuotes[i].y + 10);
			noStroke();
		}
		curQuotes[i].z++;
		if(curQuotes[i].z > 30) {
			curQuotes[i].z = 0;
			curQuotes[i] = createVector("",0,0);
		}
	}
}

Interactions Tab

/*
-----------------Doccumentation-----------------
 
function mouseReleased()
- resets time to 0 when mouse is pressed
 
function display_stats()
- provides pop-up of time-related info
 
function fix_time(t)
- returns 2-digit numbers for 1-digit t
 
function PennerEaseOutExpo(t)
- exponential ease in for t in [0,1]
-------------------------------------------------
*/
 
 
var time = 0;
 
//resets time to 0 when mouse is pressed
function mouseReleased() {
	reset = true;
}
 
//provides pop-up of time-related info
function display_stats() {
	var hr = hour()
	hr = fix_time(hr);
	var min = minute();
	min = fix_time(min);
	var sec = second();
	sec = fix_time(sec);
	var mon = month();
	var today = day();
	var fst = 0;
	var snd = today%10;
	if(today >= 10)
		first = int(today/10);
 
	fill(0,90);
	var scle = abs(PennerEaseOutExpo(map(time,0,10,0,1)));
	if(scle > 1)
		scle = 1;
	push();
	translate(width/2,height/2);
	scale(scle);
	rect(0,0,0.9*width,0.9*height);
	translate(-width/2,-height/2);
 
	fill(0);
	textSize(20);
	text("Fence Claimed By",width/2+1,height/2-125+1);
	text("Students on",width/2-200+1,height/2+1);
	text("Campus",width/2-200+1,height/2+20+1);
	text("Used Rooms",width/2+1,height/2+1);
	text("Left Wing Hunt",width/2+1,height/2+20+1);
	text("Used Rooms",width/2+200+1,height/2+1);
	text("Right Wing Hunt",width/2+200+1,height/2+20+1);
	textSize(85);
	strokeWeight(2);
	stroke(0);
	textFont('Chiller');
	line(width/2-85+1,height/2-115+1,width/2+85+1,height/2-115+1);
	line(width/2-275+1,height/2+30+1,width/2-125+1,height/2+30+1);
	line(width/2-75+1,height/2+30+1,width/2+75+1,height/2+30+1);
	line(width/2+125+1,height/2+30+1,width/2+275+1,height/2+30+1);
	text(months[mon-1].x+' '+months[mon-1].y+' '+months[mon-1].z+' . '+fst+' '+snd,width/2+2,height/2-40+2);
	textSize(125);
	noStroke();
	textFont('Helvetica');
	text(hr,width/2-200+2,height/2+140+2);
	text(':',width/2-100+2,height/2+130+2);
	text(min,width/2+2,height/2+140+2);
	text(':',width/2+100+2,height/2+130+2);
	text(sec,width/2+200+2,height/2+140+2);
 
	textSize(20);
	fill('#d5bfef');
	text("Fence Claimed By",width/2,height/2-125);
	strokeWeight(2);
	stroke('#d5bfef');
	line(width/2-85,height/2-115,width/2+85,height/2-115);
	textFont('Chiller');
	textSize(85);
	text(months[mon-1].x+' '+months[mon-1].y+' '+months[mon-1].z+' . '+fst+' '+snd,width/2,height/2-40);
	noStroke();
	textFont('Helvetica');
	textSize(20);
 
 
 
	fill('#6ed8c9');
	text("Students on",width/2-200,height/2);
	text("Campus",width/2-200,height/2+20);
	fill('#ff7551');
	text("Used Rooms",width/2,height/2);
	text("Left Wing Hunt",width/2,height/2+20);
	fill('#ffcb60');
	text("Used Rooms",width/2+200,height/2);
	text("Right Wing Hunt",width/2+200,height/2+20);
 
	strokeWeight(2);
	stroke('#6ed8c9');
	line(width/2-275,height/2+30,width/2-125,height/2+30);
	stroke('#ff7551');
	line(width/2-75,height/2+30,width/2+75,height/2+30);
	stroke('#ffcb60');
	line(width/2+125,height/2+30,width/2+275,height/2+30);
	noStroke();
 
	textSize(125);
	fill('#6ed8c9');
	text(hr,width/2-200,height/2+140);
	fill('#d5bfef');
	text(':',width/2-100,height/2+130);
	fill('#ff7551');
	text(min,width/2,height/2+140);
	fill('#d5bfef');
	text(':',width/2+100,height/2+130);
	fill('#ffcb60');
	text(sec,width/2+200,height/2+140);
	pop();
	if (time < 10 && !reset)
		time++;
	if (reset)
		time--
	if (time <= 0)
		reset = false;
}
 
//returns 2-digit numbers for 1-digit t
function fix_time(t) {
	if(t < 10)
		return '0'+ t;
	else
		return t;
}
 
 
//Easing function courtesy of Golan Levin.
//exponential ease in for t in [0,1]
function PennerEaseOutExpo(t) {
  return (t==1) ? 1 : (-pow(2, -10 * t) + 1);
}