Project 06 – Abstract Clock

Explanation for this abstract clock:

  1. The sun/moon is the HOUR HAND
  2. The duck is the MINUTE HAND
  3. The clouds’ circle is the SECOND HAND
Clock diagram

/*
 * Andrew J Wang
 * ajw2@andrew.cmu.edu
 * Section A
 * Project-05
 *
 * This program draws clock
 */

//set randam numbers for the wavy lines of reflection of the sun
var rando = 0;
//set sin values for waving reed
var drR=0;

function setup() {
    createCanvas(480,480);
    background(255);
}

function draw() {
//get dates for hours, minutes, seconds,and miliseconds
var dt = new Date();
//get location for ducks (MINUTES)
var dx=480-dt.getMinutes()*8-dt.getSeconds()*8/60;
//get location for the sun (HOURS)
var dy=(18-dt.getHours()-dt.getMinutes()*1/60-dt.getSeconds()*1/3600)*300/12;

//background
background(80,50,180);

//create reflection of the sun
if (dy>-125 & dy<425)
{
    sunReflection (dy);
    push();
    //hiding the additional parts above sea level
    fill (80,50,180);
    rect(100,200,280,100);
    pop();
}

//show moon between 6PM to 6AM
if (dy<62)
{
    moon (300+dy,125);
}

else if (dy>238)
{
    moon ((dy-300),125);
}

//create moutains and their reflections
moutain(-50,300,150,100);
moutainReflection(-50,300,150,75);

moutain(50,300,110,50);
moutainReflection(50,300,110,37.5);

moutain(350,300,250,50);
moutainReflection(350,300,250,37.5);

//gradiant sky and sea
gradiantScreen (0,300);
gradiantScreenReverse (300,600);

//draw horizon
stroke(255);
strokeWeight(1);
line (0,300,width,300);

//set sun between 6AM to 6PM
if (dy>-125 & dy<425)
{
    sun(dy,125);
}

//creating lands
land2(-100,480,500,50);
land(-200,480,400,75);

//creating clouds (SECONDS)
clouds();

//creating ducks
duck(dx,350);
duck(dx+480,350);
duck(dx-480,350);

//creating reeds
reed2();
reed();

}

//gradiant sky
function gradiantScreen (y1,y2)
{       
    //for loop changing alpha values for small rectangles
    for (var k=0; k<(y2-y1); k++)
    {   
        noStroke();
        fill (255,220,220,150/(y2-y1)*k);
        rect (0,y1+k,width,1);
    }
}

//gradiant sea but the same as gradiant sky but in reverse
function gradiantScreenReverse (y1,y2)
{
    for (var k=0; k<(y2-y1); k++)
    {   
        noStroke();
        fill (255,220,220,180/(y2-y1)*k);
        rect (0,y2-k,width,1);
    }
}

//creating sun
function sun (y,r)
{       
    fill(255,255,180);
    //outline of the sun
    strokeWeight(5);
    stroke(255,255,230,50);
    var angle = acos((300-y)/(r/2));
    //make arc if parts of the sun is below horizon
    if (300-y<=r/2)
    {
        arc (width/2,y,r,r,-(Math.PI/2-angle)+Math.PI ,2*Math.PI + (Math.PI/2-angle),OPEN);
    }
    //dont make arc if it is not
    else
    {
        circle(width/2,y,r);
    }
}
//creating moon same as sun but having a different arc/circle for the missing piece
function moon (y,r)
{
    fill(255,255,180);
    strokeWeight(0);
    stroke(255,255,230,50);
    var anglem1 = acos((300-y)/(r/2));
    var anglem2 = acos((300-y+20/Math.sqrt(2))/(r/2-20));
    if (Math.abs(300-y)<r/2)
    {
        arc (width/2,y,r,r,-(Math.PI/2-anglem1)+Math.PI ,2*Math.PI + (Math.PI/2-anglem1),OPEN);
        //the missing piece
        if (300-y+20/Math.sqrt(2)<=(r/2-20))
        {   
            push();
            fill(80,50,180);
            arc (width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40,r-40,-(Math.PI/2-anglem2)+Math.PI ,2*Math.PI + (Math.PI/2-anglem2),OPEN);
            pop();
        }
        else
        {
            push();
            fill(80,50,180);
            circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
            pop();
        }
    }
    else
    {
        circle(width/2,y,r);
        push();
        fill(80,50,180);
        //the missing piece
        circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
        pop();
    }

}

//mountain reflection using bezier
function moutainReflection(mx,y,w,h)
{   
    fill(0,0,255);
    strokeWeight(0);
    bezier(mx,y,mx,y+h,mx+w,y+h*2,mx+w,y);
}

//mountaini using benzier
function moutain(mx,y,w,h)
{   
    fill(0,0,255);
    stroke(255,255,230,50);
    strokeWeight(2);
    bezier(mx,y,mx,y-h,mx+w,y-h*2,mx+w,y);
}

//making clouds
function clouds()
{
    fill(255,255,255,75);
    //getting seconds and milliseconds
    var dt = new Date();
    var x=dt.getSeconds()*8+dt.getMilliseconds()*0.008;;
    var y=480;
    push()
    translate (0,30);
    //original moving clouds
    rect(-50+x,120,200,30,15);
    rect(-70+x,155,150,20,10);
    rect(-100+x,100,150,16,8);
    //clones to make the animation look smooth
    rect(-50+x+y,120,200,30,15);
    rect(-70+x+y,155,150,20,10);
    rect(-100+x+y,100,150,16,8);

    rect(-50+x-y,120,200,30,15);
    rect(-70+x-y,155,150,20,10);
    rect(-100+x-y,100,150,16,8);
    //original moving clouds
    rect(200+x,20,250,30,15);
    rect(350+x,50,150,20,10);
    //clones to make the animation look smooth
    rect(200+x-2*y,20,250,30,15);
    rect(350+x-2*y,50,150,20,10);

    rect(200+x-y,20,250,30,15);
    rect(350+x-y,50,150,20,10);

    //seconds indicator circles
    fill(255);
    circle(0+x,120,20);
    circle(0+x-y,120,20);
    circle(0+x+y,120,20);

    pop();
}

//create reflection of the sun using noice function to make it expand
function sunReflection (y)
{   
    rando+=0.01;
    push()
    fill (255,255,255,180);
    strokeWeight(0);
    stroke (255,255,255,180);
    rectMode(CENTER);
    rect(width/2,300+(300-y)/2,noise(rando)*50+125,4,2);
    rect(width/2,300+(300-y)/2+8,noise(rando*2)*50+75,4,2);
    rect(width/2,300+(300-y)/2-8,noise(rando-1)*50+75,4,2);
    rect(width/2,300+(300-y)/2+16,noise(rando-0.5)*50+40,4,2);
    rect(width/2,300+(300-y)/2-16,noise(rando+0.5)*50+40,4,2);
    pop()
}
//land darker
function land(mx,y,w,h)
{
    fill(30,30,130);
    noStroke();
    bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//land lighter
function land2(mx,y,w,h)
{
    fill(75,75,190);
    noStroke();
    bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//duck
function duck(x,y)
{   


    fill(30,30,130,180);
    triangle (x-5,y,x-10,y+5,x-5,y+5);
    triangle (x+5,y+5,x+5,y+10,x+35,y+10);
    arc (x,y,10,10,Math.PI,2*Math.PI);
    rect (x-5,y,10,10);
    arc (x+15,y+10,40,25,0,PI,OPEN);
}
//reed
function reed()
{   
    //moving based on sin function
    var dr = Math.sin(Math.PI*drR);
    drR+=0.002;
    push();
    translate(100,500);
    rotate(dr/20);

    fill(180,120,30);
    rect(-0,-200,10,80,5);
    rect(3,-120,4,120);

    fill(190,130,60);
    rect(-40,-190,10,80,5);
    rect(-37,-110,4,120);

    fill(210,110,80);
    rect(-20,-160,10,80,5);
    rect(-17,-80,4,120);
    pop();

}
//second types of reed (blue)
function reed2()
{   
    
    var dr = Math.sin(Math.PI*drR);
    drR+=0.002;
    push();
    translate(50,500);
    rotate(-dr/20);

    fill(50,60,100);
    rect(-0,-200,10,80,5);
    rect(3,-120,4,120);

    fill(30,70,100);
    rect(-40,-190,10,80,5);
    rect(-37,-110,4,120);
    pop();
}

Leave a Reply