// Clock // Paul Bartlett // 1 October 2007 // Interactive Image int sunRadius = 20; int orbitRadius = 125; int earthRadius = 8; int dayRadius = 20; float nowMinRadius = 3; float nowMaxRadius = 4.5; float nowDiameter; float dayAngle = (month()+day()/30.4)/12*360.0-24.0; float dayAngleSpeed; float timeAngle = dayAngle+(hour()+minute()/60.0)/24*360; float nightAngle; float earthX, earthY; float timeX, timeY; boolean inCircle = false; void setup(){ size(600,400); smooth(); } void draw(){ background(255); // Show current time state if mouse outside orbit if(sq(mouseX-width/2)+sq(mouseY-height/2) > sq(orbitRadius)){ // If far away from current time, smoothly return in shorter direction if(inCircle == true){ if(dayAngle - ((month()+day()/28.0)/12*360.0-24) < -180 || (dayAngle - ((month()+day()/28.0)/12*360.0-24) > 0)){ dayAngleSpeed = -8; } else{ dayAngleSpeed = 8; } } // If near current time, become current time if(dayAngle < ((month()+day()/28.0)/12*360.0-24) +0.1 && dayAngle > ((month()+day()/28.0)/12*360.0-24) -0.1){ dayAngle = (month()+day()/28.0)/12*360.0-24; // Current day of year timeAngle = dayAngle+(hour()+minute()/60.0)/24*360; // Current time of day dayAngleSpeed = 0; inCircle = false; } } // Increase rate of time if mouse inside orbit else{ inCircle = true; if(sq(mouseX-width/2)+sq(mouseY-height/2) > sq(20)){ dayAngleSpeed = 4000/(sq(mouseX-width/2)+sq(mouseY-height/2)); } } // Update day & time angles dayAngle = (dayAngle + dayAngleSpeed/50)%360; if(dayAngle<0){ dayAngle+=360; } timeAngle = (timeAngle + 365*dayAngleSpeed/50)%360; // Render clock drawClock(dayAngle,timeAngle); } void drawClock(float dayAngle, float timeAngle){ // Calculate Earth & Now (time) positions earthX = width/2+orbitRadius*cos(radians(360-dayAngle)); earthY = height/2-orbitRadius*sin(radians(360-dayAngle)); timeX = earthX+dayRadius*cos(radians(360-timeAngle)); timeY = earthY-dayRadius*sin(radians(360-timeAngle)); nightAngle = 180+45*sin(radians(dayAngle+90)); // Draw orbit noFill(); stroke(150); strokeWeight(0.8); ellipse(width/2,height/2,orbitRadius*2,orbitRadius*2); // Draw orbit solstice & equinox ticks strokeWeight(1); stroke(140); line(width/2+orbitRadius-3,height/2,width/2+orbitRadius+3,height/2); line(width/2-orbitRadius-3,height/2,width/2-orbitRadius+3,height/2); line(width/2,height/2+orbitRadius-3,width/2,height/2+orbitRadius+3); line(width/2,height/2-orbitRadius-3,width/2,height/2-orbitRadius+3); // Draw night cone noStroke(); fill(0); // Night arc(earthX,earthY,1000,1000,radians(dayAngle-nightAngle/2),radians(dayAngle+nightAngle/2)); // Change day circle color /////////////////////////////////////////////// // Winter to Spring if (dayAngle > 0 && dayAngle < 90){ fill(117, 146+(189-146)*dayAngle/90, 189+(129-189)*dayAngle/90); } // Spring to Summer if (dayAngle > 90 && dayAngle < 180){ fill(117+(238-117)*(dayAngle-90)/90, 189+(179-189)*(dayAngle-90)/90, 129+(37-129)*(dayAngle-90)/90); } // Summer to Fall if (dayAngle > 180 && dayAngle < 270){ fill(238+(187-238)*(dayAngle-180)/90, 179+(70-179)*(dayAngle-180)/90, 37+(10-37)*(dayAngle-180)/90); } // Fall to Winter if (dayAngle > 270 && dayAngle < 360){ fill(187+(117-187)*(dayAngle-270)/90, 70+(146-70)*(dayAngle-270)/90, 10+(189-10)*(dayAngle-270)/90); } // Draw day circle noStroke(); ellipse(earthX,earthY,dayRadius*2,dayRadius*2); // Draw Now pulse strokeWeight(.5); nowDiameter = 2*((nowMaxRadius+nowMinRadius)/2)+(nowMaxRadius-nowMinRadius)*sin(2.0*PI/0.83*millis()/1000.0); //fill(0,0,80,100-70*nowDiameter/(2*nowMaxRadius)); fill(180,0,20); ellipse(timeX,timeY,nowDiameter,nowDiameter); //ellipse(width/2,height/2,4*nowDiameter,4*nowDiameter); }