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

selinal-Looking-Outwards-12

The World’s Greatest Bar Chat by Roz Dimon

http://www.rozdimon.com/digital-paintings?lightbox=i218wx

Kisses, Kisses by Yael Kanarek

http://www.yaelkanarek.com/netart/kisses-kisses-2016

Both of the pieces are a form of digital paintings or visual generations. What I admire about them is the interactive input in creating a cohesive piece. I am not aware of the algorithms used or the input audience members were allowed to share in forming the interaction, but a subject I think was overlooked was the physicality of these pieces and their linkage to audience members. I think if the interaction was an important part, the documentation of the interaction is also pivotal in display, otherwise it seems like another painting.

THE WORLD'S GREATEST BAR CHART

<em>Kisses Kisses, 2017</em>

 

selinal-Final-Project-Proposal

Running Drawings

For my final project, I would like to create some data visualizations of the running routes I do in Pittsburgh. These visualizations would be algorithmic drawings documented as a running diary of my daily or weekly runs. What I normally do not notice on a run are the larger gestures I make and the shapes, speed rates, and heart rate variations accompanying the larger gesture of a route. Mapping out these routes, and creating algorithmic drawings from the resulting shapes would not only visualize the “gestures” I am constantly making but unaware of, but also document trends on the routes which can affect my running and the way we look at a route retrospectively.  I would be using turtle functions to follow the path, and arrays and for loops to create algorithmic patterns/visuals for a more appealing visualization of how I felt that day.

selinal-Project-11

sketch

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

var turt1;
var turt2;
var turt3;

function setup() {
    createCanvas(480, 480);
    frameRate(10); //best speed for change in turtle function

}

function draw() {
	background(40, 255, 215); //aqua backround
	turt1 = makeTurtle(mouseX, mouseY); //follows mouse from center
	turt1.setColor(color(255, 0, 255)); //magenta
	turt1.setWeight(.5); //thin lines

	turt2 = makeTurtle(mouseX, mouseY); 
	turt2.setColor(color(255, 200, 0)); //orange turtles
	turt2.setWeight(4); 

	turt3 = makeTurtle(mouseX, mouseY);
	turt3.setColor(color(180, 255, 30)); //yellow turtles
	turt3.setWeight(10); //largest stroke weight span

	turt4 = makeTurtle(mouseX, mouseY);
	turt4.setColor(color(255, 100, 50));

	for(var i = 0; i < 12; i++) { //there are about 12 visible iterations of the yellow turtles 
		turt3.penDown();
		turt3.forward(random(30,35)*i); //by multiplying by i, the side lengths increase with each iteration of the turtle shape
		turt3.left(60); //constant angle for visual flow
		turt3.forward(random(30,35)*i); //larger length sides
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.penUp();
	}

	for(var i = 0; i < 18; i++) { //iterations of the orange turtles
		turt2.penDown();
		turt2.forward(random(6,10)*i); //shorter sides
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.penUp();
		turt2.left(20);
		turt2.forward(5);
	}

	for(var i = 0; i < 20; i++) { //there are about 20 visible iterations of the magenta turtles
		turt1.setWeight(i*.1); //stroke weight increases with side length of the turtle
		turt1.penDown();
		turt1.back(20*i/3); //medium scale sides scale sides
		turt1.left(random(50,70)); 
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.penUp();
		turt1.right(noise(.001)*50); //natural movement away from the other circles with noise function
		turt1.back(40);	 //constant for visual appeal
	}

	for(var i = 0; i < 50; i++) {
		turt4.setWeight(i*.04);
		turt4.penDown();
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt1.back(10*i/4);
		turt1.left(random(70,90));
		turt1.back(10*i/4);
		turt1.left(random(70,90));
		turt1.back(10*i/4);
		turt1.penUp();
		turt1.right(noise(.001)*50);
		turt1.back(80);	
	}

	if(mouseIsPressed) {
		noLoop();
	}
}


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 process for this project started with playing around with the abstraction and composition of different polygons and their color. The mouse interaction and randomization were added after.

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

var turt1;
var turt2;
var turt3;

function setup() {
    createCanvas(480, 480);
    frameRate(10); //best speed for change in turtle function

}

function draw() {
	background(40, 255, 215); //aqua backround
	turt1 = makeTurtle(mouseX, mouseY); //follows mouse from center
	turt1.setColor(color(255, 0, 255)); //magenta
	turt1.setWeight(.5); //thin lines

	turt2 = makeTurtle(mouseX, mouseY); 
	turt2.setColor(color(255, 200, 0)); //orange turtles
	turt2.setWeight(4); 

	turt3 = makeTurtle(mouseX, mouseY);
	turt3.setColor(color(180, 255, 30)); //yellow turtles
	turt3.setWeight(10); //largest stroke weight span

	turt4 = makeTurtle(mouseX, mouseY);
	turt4.setColor(color(255, 100, 50));

	for(var i = 0; i < 12; i++) { //there are about 12 visible iterations of the yellow turtles 
		turt3.penDown();
		turt3.forward(random(30,35)*i); //by multiplying by i, the side lengths increase with each iteration of the turtle shape
		turt3.left(60); //constant angle for visual flow
		turt3.forward(random(30,35)*i); //larger length sides
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.left(60);
		turt3.forward(random(30,35)*i);
		turt3.penUp();
	}

	for(var i = 0; i < 18; i++) { //iterations of the orange turtles
		turt2.penDown();
		turt2.forward(random(6,10)*i); //shorter sides
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.right(72);
		turt2.forward(random(6,10)*i);
		turt2.penUp();
		turt2.left(20);
		turt2.forward(5);
	}

	for(var i = 0; i < 20; i++) { //there are about 20 visible iterations of the magenta turtles
		turt1.setWeight(i*.1); //stroke weight increases with side length of the turtle
		turt1.penDown();
		turt1.back(20*i/3); //medium scale sides scale sides
		turt1.left(random(50,70)); 
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.left(random(50,70));
		turt1.back(20*i/3);
		turt1.penUp();
		turt1.right(noise(.001)*50); //natural movement away from the other circles with noise function
		turt1.back(40);	 //constant for visual appeal
	}

	for(var i = 0; i < 50; i++) {
		turt4.setWeight(i*.04);
		turt4.penDown();
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt4.back(10*i/4);
		turt4.left(random(70,90));
		turt1.back(10*i/4);
		turt1.left(random(70,90));
		turt1.back(10*i/4);
		turt1.left(random(70,90));
		turt1.back(10*i/4);
		turt1.penUp();
		turt1.right(noise(.001)*50);
		turt1.back(80);	
	}

	if(mouseIsPressed) {
		noLoop();
	}
}


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

selinal-Looking-Outwards-11

Surround Sounds by Christian Marclay

Surround Sounds is an art installation by Christian Marclay which entraps viewers in a room with projections that play “music” through their animation of visual onomatopoeias. The room is actually silent, but by using the animations to take over the space, sound can be envisioned, or felt in an alternative way. This piece shows an interesting connection between sound art and music, because the art under the category of sound art simply does not make sound. I admire this aspect of the piece. I am not sure if many algorithms were used directly in this piece, but Marclay worked with a team of animators in Adobe After Effects.

selinal-Project-10

sketch

//Selina Lee
//section C
//selinal@andrew.cmu.edu
//Project-10

var cactus = []; //tall cacti array w/ arms array
var smallCactus = []; //lower, short cacti w/o arms array


function setup() {
    createCanvas(640, 240); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 6; i++){ //there are a max of 6 objects in the array listed 
        var rx = random(width);  //randomized placement of cactus
        cactus[i] = makeCactus(rx); //creating cacti from position and read through cactus array
    }

    for(var i = 0; i < 8; i++) { //there is a max of 8 objects in listed array
    	var srx = random(width); //second varaiable for randomized placement
    	smallCactus[i] = makeSmallCactus(srx); 
    }
    frameRate(10); //slower frame rate 
}


function draw() {
    background(255, 70, 235); //purple background
    
    displayStatusString(); //displays text counting number of each object present in index
    displayHorizon(); //shows horizon line and subseding lines underneath

    updateAndDisplayCactus(); //updates position number of cactus depending on placement in array and time
    removeCactusThatHaveSlippedOutOfView(); //removes cactus out of view
    addNewCactusWithSomeRandomProbability();  //adds new object

    updateAndDisplaySmallCactus(); //same functions as bigger cactus but representation is different
    removeSmallCactusThatHaveSlippedOutOfView();
    addNewSmallCactusWithSomeRandomProbability(); 
}


function updateAndDisplayCactus(){
    // Update the building's positions, and display them.
    for (var i = 0; i < cactus.length; i++){
        cactus[i].move();
        cactus[i].display();
    }
}


function removeCactusThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var cactusToKeep = [];
    for (var i = 0; i < cactus.length; i++){
        if (cactus[i].x + cactus[i].breadth > 0) { //pushing objects into array of cacti to keep around based on present
            cactusToKeep.push(cactus[i]);
        }
    }
    cactus = cactusToKeep; // remember the surviving buildings
}


function addNewCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newCactusLikelihood = 0.007; 
    if (random(0,1) < newCactusLikelihood) { //random out of 100%
        cactus.push(makeCactus(width)); //pushing objects into array of cactus
    }
}


// method to update position of building every frame
function cactusMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function cactusDisplay() {
    fill(150, 255, 100); //liget, bright green
    stroke(50, 200, 50); //darker green stroke
    strokeWeight(1); //normal weight for stroke
    push(); //translations only to this object
    translate(this.x, height - 40); //places cactus on horison line

    beginShape(); //curve to make cactus shape emerging from ground
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 

    for(var i = 0; i < this.nArmsLeft; i++) { //loop to place randomized number of arms on left side of cactus
        beginShape();
        curveVertex(this.breadth + 120, -i*30 - 10);
        curveVertex(this.breadth/2 - 10, -i*30 - 12);
        curveVertex(this.breadth/2 - 35, -i*40 - 50);
        curveVertex(this.breadth/2 - 15, -i*40 - 45);
        curveVertex(this.breadth/2 - 10, -i*30 - 17);
        curveVertex(this.breadth + 60, -i*30 - 15);
        endShape();
    }

    for(var i = 0; i < this.nArmsRight; i++) { //loop to place randomized number of arms on right side of cactus
        beginShape();
        curveVertex(this.breadth - 120, -i*30 - 10);
        curveVertex(this.breadth/2 + 10, -i*30 - 12);
        curveVertex(this.breadth/2 + 35, -i*40 - 50);
        curveVertex(this.breadth/2 + 15, -i*40 - 45);
        curveVertex(this.breadth/2 + 10, -i*30 - 17);
        curveVertex(this.breadth - 60, -i*30 - 15);
        endShape();
    }

    pop(); //end of translated parts
}


function makeCactus(birthLocationX) { //make a cactus at given location
    var cact = {x: birthLocationX,
                breadth: random(20, 50), //width of cactus
                speed: -1.0, 
                cHeight: random(100, 200), //height of cactus
                nArmsLeft: round(random(0,5)), // number of arms to display on left
                nArmsRight: round(random(0,5)), // number of arms on right
                move: cactusMove, //function to move cactus
                display: cactusDisplay} //fucntion to draw cactus
    return cact;
}

function updateAndDisplaySmallCactus(){ //same as for updateAndDisplayCactus but for smaller cactus
    // Update the building's positions, and display them.
    for (var i = 0; i < smallCactus.length; i++){
        smallCactus[i].move();
        smallCactus[i].display();
    }
}


function removeSmallCactusThatHaveSlippedOutOfView(){ //similar as above 
    var smallCactusToKeep = [];
    for (var i = 0; i < smallCactus.length; i++){
        if (smallCactus[i].x + smallCactus[i].breadth > 0) {
            smallCactusToKeep.push(smallCactus[i]);
        }
    }
    smallCactus = smallCactusToKeep; // remember the surviving buildings
}


function addNewSmallCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newSmallCactusLikelihood = 0.007;  //small cactus array has likelihood of showing up
    if (random(0,1) < newSmallCactusLikelihood) {
        smallCactus.push(makeSmallCactus(width));
    }
}


// method to update position of building every frame
function smallCactusMove() {
    this.x += this.speed;
}
    



function smallCactusDisplay() {
	fill(130, 240, 120);  //darker, more muted green
    stroke(50, 210, 90); //darker outline
    strokeWeight(1);
    push();
    translate(this.x, height - 20); //translates to second horizon line that is lighter than the first

    beginShape(); //creates shorter tube shape of cactus emergying from ground 
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 
    pop();

}

function makeSmallCactus(birthLocationX) {
	var sCact = {x: birthLocationX,
                breadth: random(20, 50), //similar width as cactus
                speed: -1.0,
                cHeight: random(20, 80), //shorter height
                move: smallCactusMove,
                display: smallCactusDisplay}
    return sCact;

}


function displayHorizon(){
    stroke(255, 210, 80); //orange
    strokeWeight(20); //thick line
    line (0,height-50, width, height-50); //first opaque line
    stroke(255, 210, 80, 200);
    line(0, height-30, width, height-30); //second transparent line
    stroke(255, 210, 80, 140);
    line(0, height-10, width, height-10); //third, bottom-most translucent line
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Cactus = " + cactus.length; //text to display along with data available in arrays
    var secondString = "# Small Cactus = " + smallCactus.length;
    text(statusString, 5,20);  //place to display text 
    text(secondString, 5, 35);
}

//Selina Lee
//section C
//selinal@andrew.cmu.edu
//Project-10

var cactus = []; //tall cacti array w/ arms array
var smallCactus = []; //lower, short cacti w/o arms array


function setup() {
    createCanvas(640, 240); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 6; i++){ //there are a max of 6 objects in the array listed 
        var rx = random(width);  //randomized placement of cactus
        cactus[i] = makeCactus(rx); //creating cacti from position and read through cactus array
    }

    for(var i = 0; i < 8; i++) { //there is a max of 8 objects in listed array
    	var srx = random(width); //second varaiable for randomized placement
    	smallCactus[i] = makeSmallCactus(srx); 
    }
    frameRate(10); //slower frame rate 
}


function draw() {
    background(255, 70, 235); //purple background
    
    displayStatusString(); //displays text counting number of each object present in index
    displayHorizon(); //shows horizon line and subseding lines underneath

    updateAndDisplayCactus(); //updates position number of cactus depending on placement in array and time
    removeCactusThatHaveSlippedOutOfView(); //removes cactus out of view
    addNewCactusWithSomeRandomProbability();  //adds new object

    updateAndDisplaySmallCactus(); //same functions as bigger cactus but representation is different
    removeSmallCactusThatHaveSlippedOutOfView();
    addNewSmallCactusWithSomeRandomProbability(); 
}


function updateAndDisplayCactus(){
    // Update the building's positions, and display them.
    for (var i = 0; i < cactus.length; i++){
        cactus[i].move();
        cactus[i].display();
    }
}


function removeCactusThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var cactusToKeep = [];
    for (var i = 0; i < cactus.length; i++){
        if (cactus[i].x + cactus[i].breadth > 0) { //pushing objects into array of cacti to keep around based on present
            cactusToKeep.push(cactus[i]);
        }
    }
    cactus = cactusToKeep; // remember the surviving buildings
}


function addNewCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newCactusLikelihood = 0.007; 
    if (random(0,1) < newCactusLikelihood) { //random out of 100%
        cactus.push(makeCactus(width)); //pushing objects into array of cactus
    }
}


// method to update position of building every frame
function cactusMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function cactusDisplay() {
    fill(150, 255, 100); //liget, bright green
    stroke(50, 200, 50); //darker green stroke
    strokeWeight(1); //normal weight for stroke
    push(); //translations only to this object
    translate(this.x, height - 40); //places cactus on horison line

    beginShape(); //curve to make cactus shape emerging from ground
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 

    for(var i = 0; i < this.nArmsLeft; i++) { //loop to place randomized number of arms on left side of cactus
        beginShape();
        curveVertex(this.breadth + 120, -i*30 - 10);
        curveVertex(this.breadth/2 - 10, -i*30 - 12);
        curveVertex(this.breadth/2 - 35, -i*40 - 50);
        curveVertex(this.breadth/2 - 15, -i*40 - 45);
        curveVertex(this.breadth/2 - 10, -i*30 - 17);
        curveVertex(this.breadth + 60, -i*30 - 15);
        endShape();
    }

    for(var i = 0; i < this.nArmsRight; i++) { //loop to place randomized number of arms on right side of cactus
        beginShape();
        curveVertex(this.breadth - 120, -i*30 - 10);
        curveVertex(this.breadth/2 + 10, -i*30 - 12);
        curveVertex(this.breadth/2 + 35, -i*40 - 50);
        curveVertex(this.breadth/2 + 15, -i*40 - 45);
        curveVertex(this.breadth/2 + 10, -i*30 - 17);
        curveVertex(this.breadth - 60, -i*30 - 15);
        endShape();
    }

    pop(); //end of translated parts
}


function makeCactus(birthLocationX) { //make a cactus at given location
    var cact = {x: birthLocationX,
                breadth: random(20, 50), //width of cactus
                speed: -1.0, 
                cHeight: random(100, 200), //height of cactus
                nArmsLeft: round(random(0,5)), // number of arms to display on left
                nArmsRight: round(random(0,5)), // number of arms on right
                move: cactusMove, //function to move cactus
                display: cactusDisplay} //fucntion to draw cactus
    return cact;
}

function updateAndDisplaySmallCactus(){ //same as for updateAndDisplayCactus but for smaller cactus
    // Update the building's positions, and display them.
    for (var i = 0; i < smallCactus.length; i++){
        smallCactus[i].move();
        smallCactus[i].display();
    }
}


function removeSmallCactusThatHaveSlippedOutOfView(){ //similar as above 
    var smallCactusToKeep = [];
    for (var i = 0; i < smallCactus.length; i++){
        if (smallCactus[i].x + smallCactus[i].breadth > 0) {
            smallCactusToKeep.push(smallCactus[i]);
        }
    }
    smallCactus = smallCactusToKeep; // remember the surviving buildings
}


function addNewSmallCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newSmallCactusLikelihood = 0.007;  //small cactus array has likelihood of showing up
    if (random(0,1) < newSmallCactusLikelihood) {
        smallCactus.push(makeSmallCactus(width));
    }
}


// method to update position of building every frame
function smallCactusMove() {
    this.x += this.speed;
}
    



function smallCactusDisplay() {
	fill(130, 240, 120);  //darker, more muted green
    stroke(50, 210, 90); //darker outline
    strokeWeight(1);
    push();
    translate(this.x, height - 20); //translates to second horizon line that is lighter than the first

    beginShape(); //creates shorter tube shape of cactus emergying from ground 
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 
    pop();

}

function makeSmallCactus(birthLocationX) {
	var sCact = {x: birthLocationX,
                breadth: random(20, 50), //similar width as cactus
                speed: -1.0,
                cHeight: random(20, 80), //shorter height
                move: smallCactusMove,
                display: smallCactusDisplay}
    return sCact;

}


function displayHorizon(){
    stroke(255, 210, 80); //orange
    strokeWeight(20); //thick line
    line (0,height-50, width, height-50); //first opaque line
    stroke(255, 210, 80, 200);
    line(0, height-30, width, height-30); //second transparent line
    stroke(255, 210, 80, 140);
    line(0, height-10, width, height-10); //third, bottom-most translucent line
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Cactus = " + cactus.length; //text to display along with data available in arrays
    var secondString = "# Small Cactus = " + smallCactus.length;
    text(statusString, 5,20);  //place to display text 
    text(secondString, 5, 35);
}

//Selina Lee
//section C
//selinal@andrew.cmu.edu
//Project-10

var cactus = []; //tall cacti array w/ arms array
var smallCactus = []; //lower, short cacti w/o arms array


function setup() {
    createCanvas(640, 240); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 6; i++){ //there are a max of 6 objects in the array listed 
        var rx = random(width);  //randomized placement of cactus
        cactus[i] = makeCactus(rx); //creating cacti from position and read through cactus array
    }

    for(var i = 0; i < 8; i++) { //there is a max of 8 objects in listed array
    	var srx = random(width); //second varaiable for randomized placement
    	smallCactus[i] = makeSmallCactus(srx); 
    }
    frameRate(10); //slower frame rate 
}


function draw() {
    background(255, 70, 235); //purple background
    
    displayStatusString(); //displays text counting number of each object present in index
    displayHorizon(); //shows horizon line and subseding lines underneath

    updateAndDisplayCactus(); //updates position number of cactus depending on placement in array and time
    removeCactusThatHaveSlippedOutOfView(); //removes cactus out of view
    addNewCactusWithSomeRandomProbability();  //adds new object

    updateAndDisplaySmallCactus(); //same functions as bigger cactus but representation is different
    removeSmallCactusThatHaveSlippedOutOfView();
    addNewSmallCactusWithSomeRandomProbability(); 
}


function updateAndDisplayCactus(){
    // Update the building's positions, and display them.
    for (var i = 0; i < cactus.length; i++){
        cactus[i].move();
        cactus[i].display();
    }
}


function removeCactusThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge,
    // remove it from the array.  This is quite tricky, but
    // we've seen something like this before with particles.
    // The easy part is scanning the array to find buildings
    // to remove. The tricky part is if we remove them
    // immediately, we'll alter the array, and our plan to
    // step through each item in the array might not work.
    //     Our solution is to just copy all the buildings
    // we want to keep into a new array.
    var cactusToKeep = [];
    for (var i = 0; i < cactus.length; i++){
        if (cactus[i].x + cactus[i].breadth > 0) { //pushing objects into array of cacti to keep around based on present
            cactusToKeep.push(cactus[i]);
        }
    }
    cactus = cactusToKeep; // remember the surviving buildings
}


function addNewCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newCactusLikelihood = 0.007; 
    if (random(0,1) < newCactusLikelihood) { //random out of 100%
        cactus.push(makeCactus(width)); //pushing objects into array of cactus
    }
}


// method to update position of building every frame
function cactusMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function cactusDisplay() {
    fill(150, 255, 100); //liget, bright green
    stroke(50, 200, 50); //darker green stroke
    strokeWeight(1); //normal weight for stroke
    push(); //translations only to this object
    translate(this.x, height - 40); //places cactus on horison line

    beginShape(); //curve to make cactus shape emerging from ground
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 

    for(var i = 0; i < this.nArmsLeft; i++) { //loop to place randomized number of arms on left side of cactus
        beginShape();
        curveVertex(this.breadth + 120, -i*30 - 10);
        curveVertex(this.breadth/2 - 10, -i*30 - 12);
        curveVertex(this.breadth/2 - 35, -i*40 - 50);
        curveVertex(this.breadth/2 - 15, -i*40 - 45);
        curveVertex(this.breadth/2 - 10, -i*30 - 17);
        curveVertex(this.breadth + 60, -i*30 - 15);
        endShape();
    }

    for(var i = 0; i < this.nArmsRight; i++) { //loop to place randomized number of arms on right side of cactus
        beginShape();
        curveVertex(this.breadth - 120, -i*30 - 10);
        curveVertex(this.breadth/2 + 10, -i*30 - 12);
        curveVertex(this.breadth/2 + 35, -i*40 - 50);
        curveVertex(this.breadth/2 + 15, -i*40 - 45);
        curveVertex(this.breadth/2 + 10, -i*30 - 17);
        curveVertex(this.breadth - 60, -i*30 - 15);
        endShape();
    }

    pop(); //end of translated parts
}


function makeCactus(birthLocationX) { //make a cactus at given location
    var cact = {x: birthLocationX,
                breadth: random(20, 50), //width of cactus
                speed: -1.0, 
                cHeight: random(100, 200), //height of cactus
                nArmsLeft: round(random(0,5)), // number of arms to display on left
                nArmsRight: round(random(0,5)), // number of arms on right
                move: cactusMove, //function to move cactus
                display: cactusDisplay} //fucntion to draw cactus
    return cact;
}

function updateAndDisplaySmallCactus(){ //same as for updateAndDisplayCactus but for smaller cactus
    // Update the building's positions, and display them.
    for (var i = 0; i < smallCactus.length; i++){
        smallCactus[i].move();
        smallCactus[i].display();
    }
}


function removeSmallCactusThatHaveSlippedOutOfView(){ //similar as above 
    var smallCactusToKeep = [];
    for (var i = 0; i < smallCactus.length; i++){
        if (smallCactus[i].x + smallCactus[i].breadth > 0) {
            smallCactusToKeep.push(smallCactus[i]);
        }
    }
    smallCactus = smallCactusToKeep; // remember the surviving buildings
}


function addNewSmallCactusWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newSmallCactusLikelihood = 0.007;  //small cactus array has likelihood of showing up
    if (random(0,1) < newSmallCactusLikelihood) {
        smallCactus.push(makeSmallCactus(width));
    }
}


// method to update position of building every frame
function smallCactusMove() {
    this.x += this.speed;
}
    



function smallCactusDisplay() {
	fill(130, 240, 120);  //darker, more muted green
    stroke(50, 210, 90); //darker outline
    strokeWeight(1);
    push();
    translate(this.x, height - 20); //translates to second horizon line that is lighter than the first

    beginShape(); //creates shorter tube shape of cactus emergying from ground 
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(this.breadth/2 - 10, 0);
    curveVertex(0, -this.cHeight);
    curveVertex(this.breadth, -this.cHeight);
    curveVertex(this.breadth/2 + 10, 0);
    curveVertex(this.breadth/2 + 10, 0);
    endShape(); 
    pop();

}

function makeSmallCactus(birthLocationX) {
	var sCact = {x: birthLocationX,
                breadth: random(20, 50), //similar width as cactus
                speed: -1.0,
                cHeight: random(20, 80), //shorter height
                move: smallCactusMove,
                display: smallCactusDisplay}
    return sCact;

}


function displayHorizon(){
    stroke(255, 210, 80); //orange
    strokeWeight(20); //thick line
    line (0,height-50, width, height-50); //first opaque line
    stroke(255, 210, 80, 200);
    line(0, height-30, width, height-30); //second transparent line
    stroke(255, 210, 80, 140);
    line(0, height-10, width, height-10); //third, bottom-most translucent line
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Cactus = " + cactus.length; //text to display along with data available in arrays
    var secondString = "# Small Cactus = " + smallCactus.length;
    text(statusString, 5,20);  //place to display text 
    text(secondString, 5, 35);
}

My process for this project was based on a previous drawing I have done with cacti. To me, these are significant structures because they exist in some isolation from each other by their spread and spacing in the desert, away from clusters of other living organisms, so their visual existence is very extraordinary. To create the cacti in p5, I started with creating a curve shape as the base of the cactus. Then, I randomized the number of arms present on the cactus’s body, where I had to play around with trial and error in creating a curve shape which looked like a cactus arm, but also that was attached to the cactus’s main body. I then, played with creating other objects like the smaller, darker cactus and its visual randomization and its positioning on the second horizon line lower than the first, larger, lighter cactus which was on the first horizon line.

selinal-Looking-Outward-10

Work from Home

by Hanski aka Hannah Epstein

http://hannahness.com/work-from-home

Work from home was an interactive walk in installation. Users would use their phones to text short code to a number which then triggered a response on the participant’s phone. Hannah Epstein was a MFA candidate at Carnegie Mellon and TA’d one of my sculpture classes. Her work uses humor as means of expression in reflecting serious topics and consists mainly of rug-hooking, a type of soft sculpture, and video games. It was inspiring to hear her talk about her games and how she exists in the field because before, gaming in my mind belonged only to an audience and to creators of men.

selinal-Looking-Outwards-09

Sheenu-Looking Outwards-09

I enjoyed reading this blog post and learning about how artists are implementing their interactive, non-gallery work in public settings. I think that the gesture of flipping the plates in relation to the movement of water and downward movement of the eye is very clever. It creates the illusion of the fountain while also allowing more innovative room for the shape of the fountain, the movement of the water, the scale and closeness of the viewer to the work, and the interaction which initiates a change in the piece. I think especially with our most previous project, this work is relevant to expanding beyond the combination of code with two-dimensional visuals.

selinal-Project-09

sketch

var underlyingImage; //global variable for image that is not shown

function preload() {
    var myImageURL = "https://i.imgur.com/wSnQo5j.jpg"; //image of dad
    underlyingImage = loadImage(myImageURL);
}

function setup() {
    createCanvas(700, 600); 
    background(0); //black background
    underlyingImage.loadPixels(); //load pixels
    frameRate(10); //slow placement of objects when pixels called
}

function draw() {
    var px = random(width); //random x and y variables to place something at 
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1); //constrain the x and y variables for color sake
    var iy = constrain(floor(py), 0, height-1);
    var theColorAtLocationXY = underlyingImage.get(ix, iy); //getting color of each pixel
	var r = theColorAtLocationXY[0]; //r value of color
    var g = theColorAtLocationXY[1]; // g value of pixel color
    var b = theColorAtLocationXY[2]; //b value of color
    var r2 = 255- r; //opposite r value
    var g2 = 255-r; //opposite g value
    var b2 = 255 - r; //opposite b value
    noStroke(); 

    if(g < 150 & b < 150) { //if g and b values are lower, make a clear ellipse of that pixel color and a smaller circle inside that is slightly redder
    	fill(r, g, b, 170);
    	ellipse(px, py, 20, 20);
    	fill(r + 10, g - 10, b - 10);
    	ellipse(px, py, 5, 5);
    }

    if(b > 230) { //if the b value is large, make an ellipse that is bluer than the pixel and make an arrangement of other blue circles surrounding it
    	fill(r- 10, g - 10, b + 10, 150);
    	ellipse(px, py, 5, 5);
    	var numObjects = 5;
    	var angleObject = 360/numObjects;																																																							
    	for(var i = 0; i < numObjects; i++) {
    		var posX = px + random(2, 7) *cos(radians(angleObject*i) );
			var posY = py + 5 *sin(radians(angleObject*i) );
			ellipse(posX, posY, 10, 10);
    	}
    } 
    if(g > 150) { //if the green value is low, make a circle slightly greener that is random in radius
    	fill(r, g + 10, b, 100);
    	var pointSize = random(10, 60);
    	ellipse(px, py, pointSize, pointSize);
    }

    if(r > 200) { //if the r value is large, make an arrangement of circles with strokes that is slightly redder
    	var numObjects = 8;
    	var angleObject = 360/numObjects;
    	for(var i = 0; i < numObjects; i++) {
    		var posX = px + random(-5, 5) *cos(radians(angleObject*i) );
			var posY = py + 5 *sin(radians(angleObject*i) );
			noFill();
			stroke(r +20, g - 10, b - 10);
			strokeWeight(random(.25, 5));
			ellipse(posX, posY, 10, 10);
    	}
    }
    if(r < 50 & g < 50 && b < 50) { //if all r g b values are on the lower end, make a row of five circles of that color which is moving downwards to the right
    	for(var i = 0; i < 5; i++) {
    		fill(theColorAtLocationXY, 300 - i*40);
    		ellipse((px - 15) +5* i, (py-15)+ 5* i, 2, 2);
    	}
    }
    else {
    	noFill(); //if the pixel does not meet any of the conditional statements, make a blank circle with the strokeWeight random and the stroke of the color at the pixel
    	stroke(theColorAtLocationXY);
    	strokeWeight(random(1, 8));
    	ellipse(px,py, 10, 10);
    }

    var sx = mouseX; //when the mouse runs over the canvas
    var sy = mouseY;
    var mx = constrain(floor(sx), 0, width-1); //constrain the mouse value for color
    var my = constrain(floor(sy), 0, height-1);
    var theColorAtLocationMxMy = underlyingImage.get(mx, my); //color at point of mouse

    var drawSize = dist(pmouseX, pmouseY, mouseX, mouseY); //distance between mouse coordinates at previous to current point
    fill(r2, g2, b2, 200); //opposite color
    ellipse(sx, sy, drawSize/10, drawSize/10); //draw a circle with mouse stroke depending on the mouse speed
	
	if(mouseIsPressed) { //if the mouse is pressed, make a circle the color of that pixel
		fill(theColorAtLocationMxMy);
		ellipse(mouseX, mouseY, 7, 7);
	}
}




I liked playing with opacity in the shapes we make in class. I think the randomization of pixels along with the overlapping of the colors is nice.

Looking-Outwards-08

Eric Fischer

https://www.mapbox.com/about/team/eric-fischer/

Eric Fischer describes himself as a data artist and software developer, and he is based in the California bay area. His work uses data points of crime rates, traffic, transit lines, race, etc. to map the US. He said his obsession for the past few years is “what makes cities walkable.” His process consists of him carrying a GPS and first personally observing the area he is in and trying to match his walking life with what the retrospective walkability of the area is. From his personal investigations of cities, he has made art about large scale issues in the critiques of those cities, making viewers step back both physically and metaphorically. His presentation was not the most captivating, but with visuals and realistic trends I found it to be very successful. I admire the point he made about how data visualization does net necessarily have to be abstract, and that the ideas behind his work do not end up being abstract. His research thus becomes more than a realization on paper.

Image result for eric fischer

Image result for eric fischer