selinal-FinalProject

sketch

//Selina Lee
//Section C
//selinal@andrew.cmu.edu
//Final Project

var mapPic;//variable for image of map
var backPic; //background picture (collage of running in Pittsburgh)
var skiboStart; //turtle functions at different start poitns
//this one starts in front of skibo
var ovalStart; //this one occurs after reaching the schenley oval
var scaleX = 0.4; //scale down width wise from original canvas which is
// 480 / 1200
var scaleY = 0.6; //scale down height wise from original canvas whic is
// 480 / 800 

//arrays containing the points to draw run routes with turtle functions
//route titled beechwood (x and y points placed into arrays)
var beechX = [760, 789, 778, 808, 859, 895, 968, 980, 1014, 984, 1024, 950,
809, 737, 733];
var beechY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 175, 111, 125, 189,
195, 237];
//route titled the point
var pointX = [740, 726, 719, 697, 687, 695, 677, 632, 592, 568, 560, 464, 402, 
268, 219, 35, 38, 61, 104, 148, 154, 201, 162, 183, 234, 418, 463, 502, 602, 
672, 695, 732, 722, 735, 733, 745];
var pointY = [295, 298, 312, 315, 327, 353, 372, 378, 365, 389, 418, 361, 356, 
379, 370, 279, 262, 258, 242, 226, 255, 244, 314, 328, 327, 338, 352, 355, 261,
235, 236, 234, 258, 261, 270, 275];
//route titled trader joe's
var traderX = [760, 789, 778, 808, 859, 859, 968, 1059, 1064, 1062, 1098, 964, 
943, 718, 731, 737, 733, 744, 734];
var traderY = [277, 262, 244, 225, 221, 242, 242, 221, 212, 204, 138, 24, 12, 
103, 147, 194, 234, 239, 270];
//route titled tranquil
var tranquilX = [760, 789, 778, 808, 859, 895, 968, 980, 1049, 1087, 1089, 1111,
1126, 1138, 1161, 1174, 1169, 1178, 1170, 1178, 1160, 1159, 1139, 1068, 1060, 
1059, 1139, 1068, 1060, 1059, 968, 895, 859, 808, 778];
var tranquilY = [277, 262, 244, 225, 221, 242, 242, 325, 324, 338, 345, 343, 
354, 346, 362, 350, 339, 322, 301, 287, 260, 234, 217, 191, 208, 218, 245, 242,
221, 225, 244];
//warmup route to work out location titled one-eight
var eightX = [743, 732, 715, 700, 686, 695, 687, 678, 687, 674, 673, 677, 671, 
683, 683, 692, 759, 782, 787, 778, 761, 721];
var eightY = [291, 295, 310, 315, 328, 349, 365, 379, 394, 397, 406, 411, 421, 
436, 444, 449, 403, 398, 392, 385, 391, 417];
//schenley oval route
var ovalX = [714, 720, 737, 746, 757, 764, 760, 751, 741, 720, 715];
var ovalY = [411, 415, 407, 396, 393, 389, 381, 379, 379, 395, 406];
//regular cool down route from oval
var coolX = [737, 778, 789, 794, 801, 789, 776, 733, 719, 709, 709, 713, 714, 
723, 740, 746];
var coolY = [408, 387, 387, 392, 386, 378, 374, 358, 355, 342, 328, 321, 311, 
308, 296, 274];
//other cool down route from oval called ten minute
var tenX = [724, 696, 684, 689, 688, 704, 690, 712, 707, 693, 696, 690, 694, 
724, 731, 741];
var tenY = [420, 439, 426, 416, 407, 404, 385, 379, 372, 363, 351, 326, 318, 
306, 294, 293];
//run titled southside
var southX = [745, 730, 740, 727, 673, 602, 499, 465, 418, 407, 409, 431, 477, 
486, 496, 523, 576, 602, 632, 680, 675, 682, 686, 699, 761, 782, 795, 784, 733, 
712, 694, 691, 694, 724, 731, 739];
var southY = [274, 271, 235, 233, 236, 262, 352, 354, 335, 417, 454, 460, 472, 
463, 455, 477, 437, 460, 469, 460, 443, 435, 448, 448, 400, 395, 382, 376, 357, 
350, 340, 323, 315, 304, 293, 293];

var counter = 0;// counter variable to count down differet routes shown
var backColR = 0; //background R value variable
var backColG = 0; //background G value variable
var backColB = 0; //background B value variable
var backColT = 270; //background opacity value

var colorArr = []; //empty array to contain color and placement creations
//see function fillInColorArray
var colors = ["black", "yellow"]; //colors to take


function preload() {
    mapPic = loadImage("https://i.imgur.com/zIVTSXM.jpg"); //map preload
    backPic = loadImage("https://i.imgur.com/vzuo6YG.jpg"); //background image
    //preload
}

function setup() {
    createCanvas(480, 480);
    image(backPic, 0, 0, map.width, map.height);//drawing map picture
    
    //used early on in project to find array points
    /*if(mouseIsPressed) {
     print(mouseX, mouseY); 
    }*/

    skiboStart = makeTurtle(747 * scaleX, 274 * scaleY); //draws turtles that 
    //start and end at Skibo
    ovalStart = makeTurtle(712 * scaleX, 410 * scaleY); // turtles that start at 
    //Schenley Oval 
    
    //I missed the criteria to scale the canvas to 480, so I used the scale 
    //variable to reduce the size of my points
    for(var i = 0; i < beechX.length; i++) {
        beechX[i] *= scaleX;
        beechY[i] *= scaleY;
    }
    for(var i = 0; i < pointX.length; i++) {
        pointX[i] *= scaleX;
        pointY[i] *= scaleY;
    }
    for(var i = 0; i < traderX.length; i++) {
        traderX[i] *= scaleX;
        traderY[i] *= scaleY;
    }
    for(var i = 0; i < tranquilX.length; i++) {
        tranquilX[i] *= scaleX;
        tranquilY[i] *= scaleY;
    }
    for(var i = 0; i < ovalX.length; i++) {
        ovalX[i] *= scaleX;
        ovalY[i] *= scaleY;
    }
    for(var i = 0; i < eightX.length; i++) {
        eightX[i] *= scaleX;
        eightY[i] *= scaleY;
    }
    for(var i = 0; i < coolX.length; i++) {
        coolX[i] *= scaleX;
        coolY[i] *= scaleY;
    }
    for(var i = 0; i < tenX.length; i++) {
        tenX[i] *= scaleX;
        tenY[i] *= scaleY;
    }
    for(var i = 0; i < southX.length; i++) {
        southX[i] *= scaleX;
        southY[i] *= scaleY;
    }
}

function mouseClicked() {
    counter++; //when mouse is clicked, create a counter to increment
    //every time 
    backColT = backColT - 20; //with every mouse click, the background
    //transparency gets more opaque
}


function draw() {
 image(backPic, 0, 0, map.width, map.height);//underlying image to be
 //revealed
 background(backColR, backColG, backColB, backColT); //background color
 //based on variable values

 fill(255); //prints directions on how to interact with piece ==>
 //continuous clicking reveals the different routes and visuals and black 
 //and white background
 text("Click on the canvas to reveal my running log in Pittsburgh!", 30, 
  30);

 if(mouseIsPressed) {
     print(mouseX, mouseY); //helps find position of mouse on map to draw 
     //turtle before translation
    }

    translate(-8, 50); //center the marks with these units
    
    //BEECHWOOD ROUTE: 5 MILES
    if (counter == 0 || counter >= 9) { //the start of the counter and when
    	//the mouse clicks through all slides, this will be shown
        for(var i = 0; i < beechX.length; i++) { //iterate through route 
            //arrays to get points. The array length should be the same for
        	//X and Y because I manually clicked on the screen to get place
        	//numbers
            skiboStart.setColor(color(255, 0, 255)); //magenta turtle
            skiboStart.penDown(); //start drawing
            skiboStart.goto(beechX[i], beechY[i]); //drawing beechwood route 
            //based on points in beechX and beechY array
            skiboStart.penUp();//stop drawing
            
            noStroke(); 
            fill(150, 0, 255, 80); //light, see-through, purple rectangles
            //these rectangles are drawn based on the values of the points
            //and the differences of the points on the path
            rect(beechX[i - 1], beechY[i - 1], beechX[i - 1] - beechX[i], 
             beechY[i - 1] - beechY[i]);
            rect(beechX[i], beechY[i], beechX[i] - beechX[i], 
             beechY[i - 1] - beechY[i]);
            rect(beechX[i - 1], beechY[i], beechX[i] - beechX[i - 1], 
             beechY[i] - beechY[i - 1]);
            rect(beechX[i], beechY[i], beechX[i] - beechX[i - 1], 
             beechY[i] - beechY[i - 1]);
        }
    }

    //THE POINT: 9.25 MILES
    fillInColorArr(0); //see function fillInColorArr 
    //this starts the function at place 0
    if (counter == 1 || counter >= 9) { //next shown visual from counter
    	//(all visuals are shown at the end of the list)
        for(var i = 0; i < pointX.length; i++) {
             backColB = 255; //background will be light blue
             backColG = 200;
             backColR = 100;

             skiboStart.setColor(colorArr[i]); //the color of each 
             //turtle move is based on fillInColorArr (while it 
             //iterates, a value is placed into the color function out
             //of the colorArr array)
             skiboStart.setWeight(5); //thicker line
             skiboStart.penDown();
             skiboStart.goto(pointX[i], pointY[i]);
             skiboStart.penUp();

             noFill();
             stroke(255, 255, 0); //yellow thin lines
             strokeWeight(1);
             beginShape(); //curves based off of Pittsburgh bridges
             //and the curve vertex control points are based on
             //position between selected points so that some
             //abstraction is visualized from the data
             curveVertex(pointX[i], pointY[i] + 30);
             curveVertex(pointX[i], pointY[i] + 30);
             curveVertex((pointX[i] + pointX[i - 1]) / 2, 
              (pointY[i - 1] + pointY[i]) / 4);
             curveVertex((pointX[i - 1] + pointX[i]) / 2, 
              (pointY[i - 1] + pointY[i]) / 4);
             curveVertex(pointX[i - 1], pointY[i - 1] + 30);
             curveVertex(pointX[i - 1], pointY[i - 1] + 30);
             endShape();
        }
    }

    //TRADER JOE'S: 5.5 MILES
    if(counter == 2  || counter >= 9) {
        for(var i = 0; i < traderX.length; i++) {
            backColR = 255; //light purple background
            backColG = 120;
            backColB = 200;

            skiboStart.setColor(color(200, 255, 0)); //green-yellow 
            skiboStart.setWeight(1)
            skiboStart.penDown();
            skiboStart.goto(traderX[i], traderY[i]);
            skiboStart.penUp();

            for(var j = 0; j < 5; j++) { //make 5 of this command
                 noFill();
                 strokeWeight(2); 
                 stroke(255, 200, 0); //orange bullseye design at 
                 //each turtle point
                 ellipse(traderX[i], traderY[i], 10 * j, 10 * j);
            }
        }
    }

    //TRANQUIL: 6.3 MILES
    if(counter == 3 || counter >= 9) { 
        for(var i = 0; i < tranquilX.length; i++) {
            backColB = 75; //dark blu background
            backColG = 0;
            backColR = 0;

            skiboStart.setColor(color(200, 255, 0)); //green-yellow
            skiboStart.setWeight(1);
            skiboStart.goto(tranquilX[i], tranquilY[i]);
            skiboStart.penUp();

            fill(255, 230, 0, 60); //see-through orange-yellow
            //circles drawn at each tranquil turtle point
            //one on top of the other like an eye
            ellipse(tranquilX[i], tranquilY[i], 20, 20); 
            ellipse(tranquilX[i], tranquilY[i], 8, 8);

            fill(150, 255, 100, 100); //see-through green
            noStroke();
            //these ellipses were drawn towards the top right of the turtle
            //route as a conglomeration
            ellipse(tranquilX[i] + 60, tranquilY[i] - 20, 50, 50);     
            fill(100, 255, 220, 100); //see-through blue-green
            ellipse(tranquilX[i] + 50, tranquilY[i] - 40, 40, 40); 
        }
    }

    //ONE EIGHT- WARMUP ROUTE TO SCHENLEY OVAL VIA THE BRIDAL PATH: 1.8 MILES
    if(counter == 4 || counter >= 9) {
        for(var i = 0; i < eightX.length; i++) {
         backColR = 255; //yellow background
         backColG = 255;
         backColB = 0;

            skiboStart.setColor(color(255, 0, 0)); //red turtle
            skiboStart.setWeight(1);
            skiboStart.penDown();
            skiboStart.goto(eightX[i], eightY[i]);
            skiboStart.penUp();

            fill(255, 50, 75, 20); //fill transparent red
            var maxX = max(eightX); //maximum value in x value array
            var minX = min(eightX); //minimum value in x value array
            var midX = (maxX + minX) / 2; //average of max and min value in 
            //x array

            var maxY = max(eightY); //maximum value in y array
            var minY = min(eightY); //minimum value in y array
            var midY = (maxY + minY) / 2; //avverage of max and min value in 
            //y array
            var curveX1; //first control x value point 
            var curveY1; //first control y value point
            var curveX2; //control two x value point
            var curveY2; //control two y value point

            if(eightX[i] < midX) { //if the turtle point is to the left of the 
             //"center"
             curveX1 = eightX[i] + 10; //if using bezier curve function, the 
             //first control point goes towards the middle 
             curveX2 = eightX[i] - 10; //then the second control point goes 
             //away from the center
            } else { //to the right of "center"
             curveX1 = eightX[i] - 10; //towards middle
             curveX2 = eightX[i] + 10; //away from center
            }

            if(eightY[i] < midY) { //if the turtle point is to the top of the 
             //middle of the route loop
             curveY1 = eightY[i] + 10; //the first control point goes down 
             //towards the center
             curveY2 = eightY[i] - 10; //second goes away from
            } else { //to bottom of route
             curveY1 = eightY[i] - 10; //first control point towards middle
             curveY2 = eightY[i] + 10; //away from middle
            }

            stroke(255, 100, 100, 200); //red
            strokeWeight(0.5);
            //the curves meet at a midpoint
            bezier(eightX[i], eightY[i], curveX1, curveY1, curveX2, curveY2, 
             midX, midY);
            bezier(eightX[i], eightY[i], curveX2, curveY2, curveX1, curveY1, 
             midX, midY);
        }
    }

    //OVAL LOOP = .625 MILES
    if(counter == 5 || counter >= 9) {
        for(var i = 0; i < ovalX.length; i++) {
            stroke(255, 100, 255, 70); //light magenta
            strokeWeight(40); //very thick line
            //used a line so the turtle function does not get confused 
            //and hide the movement created visually.
            //this line makes the same route as the turtle function
            line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);

            stroke(100, 150, 255, 120); //overlapping light blue lines
            //on top of oval lap so you can still see the purple underneath
            strokeWeight(15);
            line(ovalX[i - 1], ovalY[i - 1], ovalX[i], ovalY[i]);

            stroke(255, 200, 0); //orange turtle on top of laps
            strokeWeight(3);
            line(ovalX[i], ovalY[i], ovalX[i - 1], ovalY[i - 1]);
        }
    }

    //COOL DOWN ROUTE FROM SCHENLEY OVAL VIA PANTHER HOLLOW TRAIL: 1.3 MILES
    if(counter == 6 || counter >= 9) {
        for(var i = 0; i < coolX.length; i++) {
            ovalStart.setColor(color(0, 100, 255)); 
            ovalStart.setWeight(1);
            ovalStart.penDown();
            ovalStart.goto(coolX[i], coolY[i]);
            ovalStart.penUp();

            fill(100, 150, 255, 30);
            var maxX = max(coolX); //maximum value in x value array
            var minX = min(coolX); //minimum value in x value array
            var midX = (maxX + minX) / 2; //average of max and min value in 
            //x array

            var maxY = max(coolY); //maximum value in y array
            var minY = min(coolY); //minimum value in y array
            var midY = (maxY + minY) / 2; //avverage of max and min value in 
            //y array
            var curveX1; //first control x value point 
            var curveY1; //first control y value point
            var curveX2; //control two x value point
            var curveY2; //control two y value point

            if(coolX[i] < midX) { //if the turtle point is to the left of the 
                //"center"
                curveX1 = coolX[i] + 10; //if using bezier curve function, the 
                //first control point goes towards the middle 
                curveX2 = coolX[i] - 10; //then the second control point goes 
                //away from the center
            } else { //to the right of "center"
                 curveX1 = coolX[i] - 10; //towards middle
                 curveX2 = coolX[i] + 10; //away from center
            }

            if(coolY[i] < midY) { //if the turtle point is to the top of the 
                //middle of the route loop
                curveY1 = coolY[i] + 10; //the first control point goes down 
                //towards the center
                curveY2 = coolY[i] - 10; //second goes away from
            } else { //to bottom of route
                curveY1 = coolY[i] - 10; //first control point towards middle
                curveY2 = coolY[i] + 10; //away from middle
            }

            stroke(0, 200, 255, 200);
            strokeWeight(.5);
            bezier(coolX[i], coolY[i], curveX1, curveY1, curveX2, curveY2, midX,
             midY);
            bezier(coolX[i], coolY[i], curveX2, curveY2, curveX1, curveY1, midX, 
             midY);
        }
    }

    //TEN MINUTE COOL DOWN: 1.1 MILES
   if(counter == 7 || counter >= 9) {
       for(var i = 0; i < tenX.length; i++) {
           ovalStart.setColor(color(0, 150, 255));
           ovalStart.penDown();
           ovalStart.goto(tenX[i], tenY[i]);
           ovalStart.penUp();

           fill(20, 20, 255, 30);
           var maxX = max(tenX); //maximum value in x value array
           var minX = min(tenX); //minimum value in x value array
           var midX = (maxX + minX) / 2; //average of max and min value in 
           //x array

           var maxY = max(tenY); //maximum value in y array
           var minY = min(tenY); //minimum value in y array
           var midY = (maxY + minY) / 2; //avverage of max and min value in 
           //y array
           var curveX1; //first control x value point 
           var curveY1; //first control y value point
           var curveX2; //control two x value point
           var curveY2; //control two y value point

           if(tenX[i] < midX) { //if the turtle point is to the left of the 
               //"center"
               curveX1 = tenX[i] + 10; //if using bezier curve function, the 
               //first control point goes towards the middle 
               curveX2 = tenX[i] - 10; //then the second control point goes 
               //away from the center
            } else { //to the right of "center"
               curveX1 = tenX[i] - 10; //towards middle
               curveX2 = tenX[i] + 10; //away from center
            }

            if(tenY[i] < midY) { //if the turtle point is to the top of the 
                //middle of the route loop
                curveY1 = tenY[i] + 10; //the first control point goes down 
                //towards the center
                curveY2 = tenY[i] - 10; //second goes away from
            } else { //to bottom of route
                curveY1 = tenY[i] - 10; //first control point towards middle
                curveY2 = tenY[i] + 10; //away from middle
            }

            stroke(0, 150, 255, 200);
            strokeWeight(0.5);
            bezier(tenX[i], tenY[i], curveX1, curveY1, curveX2, curveY2, midX, 
             midY);
            bezier(tenX[i], tenY[i], curveX2, curveY2, curveX1, curveY1, midX, 
             midY);
     }
  }

  //SOUTHSIDE: 6.6 MILES
  if(counter == 8 || counter >= 9) {
      for(var i = 0; i < southX.length; i++) {
      	  backColG = 255; //green background
      	  backColR = 50;
      	  backColB = 100;

          skiboStart.setColor(color(255, 0, 255)); 
          skiboStart.penDown();
          skiboStart.goto(southX[i], southY[i]);
          skiboStart.penUp();

          stroke(255, 50, 100); //red
          fill(255, 120, 50, 50); //transparent red orange
          //lines drawn to create turtle skeleton
          line(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20);
          line(southX[i] * 0.9, southY[i] + 20, southX[i - 1] * 0.9, 
          southY[i - 1] + 20); 
          line(southX[i - 1] * 0.9, southY[i - 1] + 20, southX[i] * 0.85, 
          southY[i] - 30);
          line(southX[i] * 0.85, southY[i] - 30, southX[i - 1] * 0.85, 
          southY[i - 1] - 30);
          line(southX[i] * 0.85, southY[i] - 30, 180, 330);

          noStroke();
          //triangles based off of parameters to create line skeleton
          triangle(southX[i], southY[i], southX[i] * 0.9, southY[i] + 20,
          southX[i - 1] * 0.9, southY[i - 1] + 20);
          triangle(southX[i - 1] * 0.9, southY[i - 1] + 20, 
          southX[i] * 0.85, southY[i] - 30, 180, 330)
       }
  }
}

function fillInColorArr(filledSoFar) { //recursive function to change color
	//every action of the turtle 
    if(filledSoFar == 0) { //if nothing has been drawn yet, leave the array 
        colorArr = []; 
        colorArr.push(colors[0]); //push the colors from colors array into
        //colorArr so that they can be used and start from 0 which is "black"
        var currentFillNumber = filledSoFar + 1; //counts which property has
        //recieved a color to use
        fillInColorArr(currentFillNumber); //fill in this area with the color
        //corresponding to the placement of the turtle in its start point in 
        //its array
    } else if(filledSoFar >= pointX.length) {
        return;
    } else { //if the paremeters that have been filled so far do not exceed 
    	//the length of the point array, do the same as if nothing has been
    	//drawn yet and give the parameter a color to use
        colorArr.push(colors[filledSoFar % colors.length]);
        var currentFillNumber = filledSoFar + 1;
        fillInColorArr(currentFillNumber);
    }
}

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;
}

Leave a Reply