//Garrett Rauck
//Section C
//grauck@andrew.cmu.edu
//Project-06-Abstract Clock
//In this clock, the hour is represented by the greyscale tone of the background,
//the minute is represented by the rotation of the line, and the second is
//represented by the inflection of the line which is a 6-bit binary representation
//of the integer value of the second.
/////////////////////////////////
// GLOBAL VARS
/////////////////////////////////
//canvas
var canvasWidth, canvasHeight;
//time
var h, m, s;
//geometry
var x = []; //x pts of line
var y = []; //y pts of line
var nBits, ptsPerBit, nPts, ptSpacing;
var bitVal, bit0Amplitude, bit1Amplitude;
var rotationAngle;
var seeTime;
var mBallSize, sBallSize, cBallSize;
//color
var cBackground, cStroke;
/////////////////////////////////
// HELPER FNS
/////////////////////////////////
function drawWave() {
for (var i = 0; i < x.length-1; i++) {
stroke(cStroke);
push(); //rotation for minute
translate(canvasWidth/2, canvasHeight/2); //translate to origin
rotate(rotationAngle); //rotate based on current minute
translate(-canvasWidth/2, -canvasHeight/2); //translate back to position.
line(x[i], y[i], x[i+1], y[i+1]); //draw line
pop();
}
}
function drawSBall() {
var armLength = canvasWidth/4-sBallSize/2;
var theta = s*(TWO_PI/60) - HALF_PI;
var cx = canvasWidth/2 + armLength*cos(theta);
var cy = canvasHeight/2 + armLength*sin(theta);
stroke(0);
noFill();
ellipse(cx, cy, sBallSize);
}
function drawMBall() {
var armLength = canvasWidth/2-mBallSize/2;
var theta = rotationAngle;
var cx = canvasWidth/2 + armLength*cos(theta);
var cy = canvasHeight/2 + armLength*sin(theta);
noStroke();
fill(0);
ellipse(cx, cy, mBallSize);
}
function drawCBall() {
noStroke();
fill(0);
ellipse(canvasWidth/2, canvasHeight/2, cBallSize);
}
function drawTime() {
var h = hour()%12;
var m = minute();
var s = second();
noStroke();
fill(cStroke);
text("" + nf(h,2,0) + ":" + nf(m,2,0) + ":" + nf(s,2,0), canvasWidth/2, 3*canvasHeight/4);
}
//adapted from fernandosavio's function on Stack Overflow
//http://stackoverflow.com/questions/9939760/how-do-i-convert-an-integer-to-binary-in-javascript
function getBinString(n){
//return binary string for input number with specified number of digits
return nf((n >>> 0).toString(2), nBits);
}
function updateTime() {
h = hour();
m = minute();
s = second();
}
function updatePts() {
//clean pts lists
x = [];
y = [];
//get binary string for seconds count
binString = getBinString(s); //convert second to binary, return string
//get x and y values for pts
for (i = 0; i < nBits; i++) { //for each bit
bitVal = int(binString[i]);
for (j = 0; j < ptsPerBit; j++) { //for each pt in bit
x.push(i*ptsPerBit*ptSpacing+j*ptSpacing); //x value
if (bitVal == 0) {
yMax = bit0Amplitude;
yMin = -bit0Amplitude;
}
else {
yMax = bit1Amplitude;
yMin = -bit1Amplitude;
}
y.push(canvasHeight/2 + random(yMax, yMin)) //y value
}
}
}
function updateRotation() {
rotationAngle = m*(TWO_PI/60) + HALF_PI;
}
function updateColors() {
cStroke = color(h*(255/24)); // greyscale tone, hr0 = 0, hr24 = 255
cBackground = color(255-h*(255/24)); //greyscale tone, hr0 = 255, hr24 = 0
}
function updateModel() {
updateTime();
updatePts();
updateRotation();
updateColors();
}
/////////////////////////////////
// EVENTS
/////////////////////////////////
function keyPressed() {
if (seeTime == false) seeTime = true;
else seeTime = false;
}
/////////////////////////////////
// RUN
/////////////////////////////////
function setup() {
// INIT VARS
//canvas
canvasWidth = canvasHeight = 400;
//time
h = hour();
m = minute();
s = second();
//geometry
nBits = 6; //max second count will be 59, which is 111011 in binary, 6 bits
ptsPerBit = 25; //density of "bits" represented graphically
nPts = nBits*ptsPerBit;
ptSpacing = canvasWidth/nPts;
bit0Amplitude = 5;
bit1Amplitude = 50;
seeTime = false;
mBallSize = 15;
sBallSize = 8;
cBallSize = 5;
//canvas setup
createCanvas(canvasWidth, canvasHeight);
ellipseMode(CENTER);
//initial list setup
// rotateMinuteHand();
updateModel();
}
function draw() {
//update model
updateModel();
//draw background
background(cBackground);
//draw wave
drawWave();
//draw minute ball
drawMBall();
//draw minute ball
drawSBall();
//draw center ball
// drawCBall();
//draw actual time
if (seeTime == true) {
drawTime();
}
}
The aesthetic of this clock was inspired by an exhibit by Martin Messier, which I had the chance to experience at Pittsburgh’s Wood Street Galleries over the summer. I wanted to explore creating a visual drama through the activation of a single line. I used randomness to generate “noise” in the line to give a sense of constant movement, time passing. The “bands” that form within the line change every second and are a 6-bit binary representation of the second count, from 0 to 59; the bands with the larger amplitude represent 1’s, while the bands with the smaller amplitude represent 0’s. The minute is complete when the line returns to flat, then the binary counting begins again. The minute is represented by the rotation of the line and the ball at the end, while the hour is represented by the grey-scale tone change throughout the 24-hour period–white at 00:00, black at 23:00.