Emily Zhou –– Composition

tortle

var ttl;

function setup() {
    createCanvas(400, 400);
}

function coolShape(ttl) {
    var count = 100;
    for (var i = 0; i < width; i++) {
        ttl.forward(10);
        var mx = map(mouseX, 50, 400, 200, 400);
        ttl.left(mx * 0.01 * sin(radians(i)));
        count += 1;
    }
}

function draw() {
    background("Lavender");
    for (var i = 0; i < 20; i++) {
        ttl = makeTurtle(width / 2, height / 2);
        ttl.left((360 / 20) * i);
        ttl.penDown();
        var R = map(mouseX, 0, width, 200, 255);
        ttl.setColor(color(R, 255, 255));
        ttl.setWeight(3);
        coolShape(ttl);
    }
}

//////////////////////////////


function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I wanted to use turtle graphics to create an interesting line composition that interacts with the mouse based on shape and colour. I had fun experimenting with slight differences in numerical values that drastically changed the result.

Screenshots of the composition at varying mouse positions:

Judy Li-Project-11-Composition

judyli: Composition Project 11

/*
Judy Li
Section A
judyli@andrew.cmu.edu
Project-11
*/

var ttl1 = [];//turtle 1
var ttl2 = [];//turtle 2
var ttl3 = [];//turtle 3
var ttl4 = [];//turtle 4
var opacity = 255;//starting color

function setup() {
    createCanvas(480, 480);
    background("white");
    strokeJoin(MITER);
    strokeCap(PROJECT);
    //ttl1
    for (var i = 0; i < 10; i++) {
        ttl1.push(makeTurtle(0, 0));
        ttl1[i].penDown();
        ttl1[i].right(36 * i);
    }
    //ttl2
    for (var j = 0; j < 10; j++) {
        ttl2.push(makeTurtle(480, 0));
        ttl2[j].penDown();
        ttl2[j].left(36 * j);
    }
    //ttl3
    for (var k = 0; k < 10; k++) {
        ttl3.push(makeTurtle(0, 480));
        ttl3[k].penDown();
        ttl3[k].right(36 * k);
    }
    //ttl4
    for (var l = 0; l < 10; l++) {
        ttl4.push(makeTurtle(480, 480));
        ttl4[l].penDown();
        ttl4[l].left(36 * l);
    }
}

function draw() {
    var dir = random(15, 90);
    var dist = random(10, 25);
    if (opacity > 100) {
        opacity -= 10;
    }
    else opacity = 205;
    for (var i = 0; i < 10; i++) {
        //1
        ttl1[i].setColor(opacity);
        ttl1[i].setWeight(2);
        ttl1[i].forward(dist);
        ttl1[i].right(dir);
        //2
        ttl2[i].setColor(opacity);
        ttl2[i].setWeight(2);
        ttl2[i].forward(dist);
        ttl2[i].left(dir);
        //3
        ttl3[i].setColor(opacity);
        ttl3[i].setWeight(2);
        ttl3[i].forward(dist);
        ttl3[i].right(dir);
        //4
        ttl4[i].setColor(opacity);
        ttl4[i].setWeight(2);
        ttl4[i].forward(dist);
        ttl4[i].left(dir);
    }
}


function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

For this project, I wanted to create a turtle pattern that fills up the background. I made turtles at four different starting points so that the canvas is filled up more quickly and with more depth of color through differences in color as they move about. When I played with different moves and directions, I liked this composition the best because it looks like the way a knit hat is supposed to be made.

Knit hat coming together almost
Completed knit hat

Eliza Pratt – Project 11

click to redraw!

/*
Eliza Pratt
Section E
elpratt@andrew.cmu.edu
Project 11
*/

var face = 5; //face size
var faceY = 100; //starting y coordinate for face
var w = 2; //stroke weight
var eye = {LX: 0, LY: 0, RX: 0, RY: 0}; // eye coordinates
var lipX; // lip x position
var lipY; //lip y position

function setup() {
    createCanvas(480, 360);
    frameRate(10);
}

function draw() {
    background("beige");

    for (var i = 0; i < 3; i++) {
      var turt = makeTurtle(90 + i * 150, faceY);
      turt.penDown();
      turt.setColor("black");

      //draw face features
      faceBrowsNose(turt);
      eyes(turt);
      glasses(turt);
      lips(turt);
    }

    noLoop();

}

//redraw face when the mouse is pressed
function mousePressed() {
  draw();
}


//draws face, eyebrows and nose
function faceBrowsNose(ttl) {
  //FACE
  for (var i = 0; i < 180; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 100 + random(-2.5, 2.5));
    ttl.forward(face + random(-face / 3, face / 3));
  }
  ttl.left(20);

  //LEFT EYEBROW
  for (var i = 0; i < 50; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 100);
    ttl.forward(2 + random(-2, 2));
    //save coordinates at top of brow to assign eye position
    if (i == 25) {
      eye.LX = ttl.x;
      eye.LY = ttl.y + random(10, 25);
    }
  }
  //LEFT NOSE
  for (var i = 0; i < 10; i++) {
    turtlepressure(ttl);
    ttl.right(random(-0.5, .5));
    ttl.forward(1);
  }
  //BOTTOM NOSE
  for (var i = 0; i < 50; i++) {
    turtlepressure(ttl);
    ttl.left(360 / 100);
    ttl.forward(0.5 + random(-1, 1));
    //save bottom of nose coordinates for lip position
    if (i == 25) 
      lipY = ttl.y + random (20, 30);
      lipX = ttl.x + random (-30, 10);
  }
  //RIGHT NOSE
  for (var i = 0; i < 10; i++) {
    turtlepressure(ttl);
    ttl.right(random(-0.5, .5));
    ttl.forward(1);
  }
  //RIGHT EYEBROW
  for (var i = 0; i < 50; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 100);
    ttl.forward(2 + random(-2, 2));
    if (i == 25) {
      eye.RX = ttl.x;
      eye.RY = ttl.y  + random(10, 25);
    }
  }
}


//draws eyes
function eyes(ttl) {
    ttl.penUp();
    ttl.goto(eye.LX, eye.LY);
    ttl.penDown();

    //left eye
    for (var i = 0; i < 100; i++) {
      turtlepressure(ttl);
      ttl.right(360 / 50);
      ttl.forward(.5 + random(-0.75, 0.75));
    }

    ttl.penUp();
    ttl.goto(eye.RX, eye.RY);
    ttl.penDown();

    //right eye
    for (var i = 0; i < 100; i++) {
      turtlepressure(ttl);
      ttl.right(360 / 50);
      ttl.forward(.5 + random(-0.75, 0.75));
    }
}


//draws glasses
function glasses(ttl) {
  ttl.penUp();
  ttl.goto(eye.LX + random(10, 18), eye.LY);
  ttl.penDown();

  //lens 1
  ttl.face(90);
  for (var i = 0; i < 100; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 50 + random(-4, 4));
    ttl.forward(2 + random(-0.75, 0.75));
  }

  ttl.penUp();
  ttl.goto(eye.RX - random(10, 18), eye.RY);
  ttl.face(330);
  ttl.penDown();

  //lens 2
  ttl.face(270);
  for (var i = 0; i < 100; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 50 + random(-4, 4));
    ttl.forward(2 + random(-0.75, 0.75));
  }
}


//draws lips
function lips(ttl) {

  ttl.penUp();
  ttl.goto(lipX, lipY);
  ttl.penDown();
  ttl.face(310);

  //TOP LEFT
  for (var i = 0; i < 20; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 100);
    ttl.forward(1 + random(-1, 1));
  }
  ttl.left(50);

  //TOP RIGHT
  for (var i = 0; i < 20; i++) {
    turtlepressure(ttl);
    ttl.right(360 / 100);
    ttl.forward(1 + random(-1, 1));
  }
  ttl.face(180);

  //LINE
  for (var i = 0; i < 30; i++) {
    turtlepressure(ttl);
    ttl.forward(1);
    ttl.right(random(-2, 2));
  }
  ttl.face(90);

  //BOTTOM LIP
  for (var i = 0; i < 50; i++) {
    turtlepressure(ttl);
    ttl.left(360 / 100);
    ttl.forward(1 + random(-1, 1));
  } 
}


//varies stroke weight to create "hand drawn" effect
function turtlepressure(turtle) {
  w += random(-0.4, 0.4);
  if (w <=0) w = 0.4;
  else if (w>= 3) w = 2.7;
  turtle.setWeight(w);

} 

/////////////////////////////////////////////////////////////////
function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

Ever since our second variable face assignment where we saw examples of Moka’s generative faces, I’ve wanted to code doodles that look blind contours! I had a lot of fun playing with the turtles and got some pretty great results from randomizing different things. Also, by randomizing the stroke weight for each point I was able to make my own “brush” of sorts. It was challenging to have any control over the randomness factor, but here are some of the beautiful creations that came out of it before I decided to do multiple faces:

friend with hair
derp
sleepy friend
abstract friend

Kade Stewart – Project 11 – Composition

ants

//Kade Stewart
//Section B
//kades@andrew.cmu.edu
//Project-11

//variables storing each of the ants, the repellent values, 
//and the foot variables
var ants = [];
var rpx;
var rpy;
var rpc = 0;
var foot = false;
var time = 0;


function setup() {
    createCanvas(480, 480);
    rectMode(CENTER);

    stroke(255);
    strokeWeight(6);
    strokeJoin(MITER);
    strokeCap(PROJECT);

    //initialize all of the ants (which are actually each of type turtle)
    for (var i = 0; i < 100; i++) {
        ants[i] = makeTurtle(random(0, width), random(0, height));
        ants[i].face(random(0, 360));
        ants[i].penDown();
        ants[i].setWeight(4);
        ants[i].setColor(255);
    }

}

function mousePressed() {
    //when the mouse is pressed, start the foot step

    foot = true;
    time = 120;
    rpx = mouseX;
    rpy = mouseY;
}

function draw() {
    background(0);
    

    //loop through each of the ants in the list
    for (var i = 0; i < ants.length; i++) {
        var t = ants[i];


        //if a foot is coming (if the mouse has been clicked)
        //make the ants start to avoid the shadow of the foot
        if (foot) {
            var d = dist(t.x, t.y, rpx, rpy);
            var f = rpc / (Math.pow(d, 2));
            var dirx = (t.x - rpx) / d;
            var diry = (t.y - rpy) / d;
            t.x += dirx * f;
            t.y += diry * f;
        }


        //make the ant wrap around the screen
        //because there are so many, it just looks like new ones are being added
        if (t.x >= width) {
            t.x -= width;
        } else if (t.x <= 0) {
            t.x += width;
        }
        if (t.y >= height) {
            t.y -= height;
        } else if (t.y <= 0) {
            t.y += height;
        }


        //actually move the ant...finally
        t.forward(5);

    }


    //if the foot is still terrorizing the ants (if there is still time),
    //decrease the time limit and make the repellent force larger
    //otherwise, make sure the foot variable is false
    if (time != 0) {
        time--;
        rpc = map(time, 120, 0, 0, 25000);
    } else {
        foot = false;
    }

    //if the foot is more than 1/3 of a second away, draw it's growing shadow
    //otherwise, the foot will start to stomp on the ground
    if (time >= 20) {
        noStroke();
        fill(255);
        ellipse(rpx, rpy, 100 - map(time, 0, 120, 0, 100), 100 - map(time, 0, 120, 0, 100));
    } else if (time > 0 & time < 20) {
        fill(210, 180, 140);
        noStroke();
        push();
        translate(rpx, rpy);
        scale(abs(- 2.5 + time/4));
        angleMode(DEGREES);
        rotate(5);
        rect(20, 45, 50, 80, 10);
        rect(0, 0, 10, 30, 10);
        rotate(5);
        rect(10, 1, 10, 30, 10);
        rotate(5);
        rect(20, 2, 10, 30, 10);
        rotate(5);
        rect(30, 3, 10, 30, 10);
        rotate(5);
        rect(40, 4, 10, 30, 10);
        pop();
        angleMode(RADIANS);
    }

    //the help text
    fill(0);
    stroke(255);
    textSize(20);
    text("click to stomp on these poor ants", width/6 + 10, 20);

}



function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

In the process of writing my code, I realized that the turtles each look like little ants. So, I made a shadow descend upon the ants, and eventually a foot try and stomp them. Don’t worry – none of them actually die, mostly because that would be annoying to code.

Plain ol screen
here comes the foot

Erin Fuller – Turtle Composition

//Erin Fuller
//SectionA
//efuller@andrew.cmu.edu
//Project 11

var t = [0, 1, 2]; //start w/ 3 turtles
var targetX = 0;

function setup() {
    createCanvas(480, 480);
    background(0);
    for (var i = 0; i < t.length; i++) { //initialize turtles
    	t[i] = makeTurtle(0, height / 2 + random(-100, 100));
	    t[i].setColor(color(random(100), random(255), random(255), 50));
	}
	frameRate(40); //slow down turtle!!!
}

function draw() {
    targetX += 1; //updates target with each frame
    var targetY = (width / 2) - 90 * sin(radians(targetX)); //sine wave

    noStroke(); //makes target curve "invisible"
    point(targetX, targetY);

    for (var j = 0; j < t.length; j++) {
	    t[j].penDown();
	    t[j].setWeight(4);  

    	t[j].forward(1.5); 
    	t[j].turnToward(targetX, targetY, 2); //orient towards sine wave
    	t[j].left(random(-5, 5)); //adds noise

    	if (targetX === width) { //restarts when reachinf edge of screen
    		targetX = 0; //restart target
    		for (var k = 0; k < t.length; k++) {
    			t[k].penUp(); //stops turtles moves them back
    			t[k].goto(0, height / 2 + random(-100, 100));
    			t[k].penDown(); //restart turtle
    		}
    	}
    }
}

function mousePressed() {
	var newTurtle = makeTurtle(mouseX,mouseY); //making new turtle at mouse press
	newTurtle.setColor(color(random(100), random(255), random(255), 50));
	t.push(newTurtle); //push turtle onto array
}


//------------------------------------------------------------------------------------  

// makeTurtle(x, y) -- make a turtle at x, y, facing right, pen down
// left(d) -- turn left by d degrees
// right(d) -- turn right by d degrees
// forward(p) -- move forward by p pixels
// back(p) -- move back by p pixels
// penDown() -- pen down
// penUp() -- pen up
// goto(x, y) -- go straight to this location
// setColor(color) -- set the drawing color
// setWeight(w) -- set line width to w
// face(d) -- turn to this absolute direction in degrees
// angleTo(x, y) -- what is the angle from my heading to location x, y?
// turnToward(x, y, d) -- turn by d degrees toward location x, y
// distanceTo(x, y) -- how far is it to location x, y?

function turtleLeft(d) {
    this.angle -= d;
}

function turtleRight(d) {
    this.angle += d;
}

function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}

function turtleBack(p) {
    this.forward(-p);
}

function turtlePenDown() {
    this.penIsDown = true;
}

function turtlePenUp() {
    this.penIsDown = false;
}

function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}

function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}

function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}

function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}

function turtleSetColor(c) {
    this.color = c;
}

function turtleSetWeight(w) {
    this.weight = w;
}

function turtleFace(angle) {
    this.angle = angle;
}

function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

My composition is three turtles chasing a sine wave, but the turtles can never catch it fully because of added noise that makes them wander off track. If you click your mouse, you add a new turtle!

Before Turtles Restarted Along with Target Curve, Oops
A Nice Turtle Chase
Faster Frame Rate Produced a Tighter Turtle Chase

Kyle Leve-Project-11-Composition

sketch

// Kyle Leve
// kleve@andrew.cmu.edu
// Section A
// Project-11-Composition

var faceWidth = 350;
var eyeSize = 50;
var irisSize = 30;
var pupilSize = 15;
var glimmerSize = 7;
var angle1 = 0;
var angle2 = 0;
var angle3 = 0;

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

function draw() {
	background(0);
    
    // Smile
    noFill();
    stroke(255);
    strokeWeight(5);
    curve(225, 300, 240, 320, 255, 320, 275, 300);

	// Eyes
	noStroke();
    fill('white'); // Left eyeball
    var eyeLX = 175;
    ellipse(eyeLX + 10, 200, eyeSize, eyeSize);

    fill('white'); // Right eyeball
    var eyeRX = width / 2 + faceWidth * 0.25;
    ellipse(eyeRX - 30, 200, eyeSize, eyeSize);

    fill(77,47,23); // Left iris
    ellipse(eyeLX + 15, 205, irisSize, irisSize);

    fill(77,47,23); // Right iris
    ellipse(eyeRX - 25, 205, irisSize, irisSize);

    fill('black'); // Left pupil
    ellipse(eyeLX + 20, 210, pupilSize, pupilSize);

    fill('black'); // Right pupil
    ellipse(eyeRX - 20, 210, pupilSize, pupilSize);

    fill('white'); // Left eye shimmer
    ellipse(eyeLX + 25, 212, glimmerSize, glimmerSize);

    fill('white'); // Right eye shimmer
    ellipse(eyeRX - 15, 212, glimmerSize, glimmerSize);

    // Creates rotating cat face, ears, and whiskers   
    if (mouseX >= 0 & mouseX <= width) {
    	var ttl1 = makeTurtle(0, 0);
	    var ttl2 = makeTurtle(0, 0);
	    var ttl3 = makeTurtle(0, 0);
	    var ttl4 = makeTurtle(0, 0);
	    ttl1.setColor('orange');
	    ttl2.setColor('orange');
	    ttl3.setColor('orange');
	    ttl4.setColor(255);
	    ttl1.setWeight(10);
	    ttl2.setWeight(10);
	    ttl3.setWeight(10);
	    ttl4.setWeight(5);
	    ttl1.penDown();
	    ttl2.penDown();
	    ttl3.penDown();
	    ttl4.penDown();

	    // Cat head
        push();
        translate(220, 380);
        rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    ttl1.left(20);
	    rotate(radians(angle1));
	    ttl1.forward(50);
	    pop();
	    angle1 = angle1 + 0.5;

        // Left ear
        push();
        translate(155, 125);
        rotate(radians(angle3));
        ttl2.left(90);
	    ttl2.forward(75);
	    ttl2.right(125);
	    ttl2.forward(75);
	    pop();

        // Right ear
        push();
        translate(335, 125);
        rotate(radians(angle3));
	    ttl3.left(90);
	    ttl3.forward(75);
	    ttl3.left(125);
	    ttl3.forward(75);
	    pop();
	    angle3 = angle3 + 5;

        // Whiskers
        push();
        translate(245, 260);
        rotate(radians(angle2));
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(10);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.right(10);
        ttl4.forward(50);
        ttl4.penUp();

        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(180);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(170);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(190);
        ttl4.forward(50);
        ttl4.penUp();
        pop();
        angle2 = angle2 + 5;
    } else { // Sets unmoving cat face if the mouse is not on the canvas
    	var ttl1 = makeTurtle(0, 0);
	    var ttl2 = makeTurtle(0, 0);
	    var ttl3 = makeTurtle(0, 0);
	    var ttl4 = makeTurtle(0, 0);
	    ttl1.setColor('orange');
	    ttl2.setColor('orange');
	    ttl3.setColor('orange');
	    ttl4.setColor(255);
	    ttl1.setWeight(10);
	    ttl2.setWeight(10);
	    ttl3.setWeight(10);
	    ttl4.setWeight(5);
	    ttl1.penDown();
	    ttl2.penDown();
	    ttl3.penDown();
	    ttl4.penDown();
        
        // Cat head
        push();
        translate(220, 380);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
	    ttl1.left(20);
	    ttl1.forward(50);
        pop();

        // Left ear
        push();
        translate(155, 125);
        ttl2.left(90);
	    ttl2.forward(75);
	    ttl2.right(125);
	    ttl2.forward(75);
        pop();

        // Right ear
        push();
        translate(335, 125);
	    ttl3.left(90);
	    ttl3.forward(75);
	    ttl3.left(125);
	    ttl3.forward(75);
        pop();

        // Whiskers
        push();
        translate(245, 260);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(10);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.right(10);
        ttl4.forward(50);
        ttl4.penUp();

        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(180);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(170);
        ttl4.forward(50);
        ttl4.penUp();
        ttl4 = makeTurtle(0, 0);
        ttl4.setColor(255);
	    ttl4.setWeight(5);
        ttl4.penDown();
        ttl4.left(190);
        ttl4.forward(50);
        ttl4.penUp();
        pop();
    }
}

function turtleLeft(d) {
    this.angle -= d;
}
 
 
function turtleRight(d) {
    this.angle += d;
}
 
 
function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}
 
 
function turtleBack(p) {
    this.forward(-p);
}
 
 
function turtlePenDown() {
    this.penIsDown = true;
}
 
 
function turtlePenUp() {
    this.penIsDown = false;
}
 
 
function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}
 
 
function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}
 
 
function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}
 
 
function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}
 
 
function turtleSetColor(c) {
    this.color = c;
}
 
 
function turtleSetWeight(w) {
    this.weight = w;
}
 
 
function turtleFace(angle) {
    this.angle = angle;
}
 
 
function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

I decided for this project I would use turtles to create a cat. I found it interesting that with lines I was still able to make circular shapes such as the head of the cat. In addition I decided to mess around with the rotation function to make the cat seems to break apart when the mouse is on the canvas. However, once the mouse is off the campus, the image would return to its original cat face.