ashleyc1-Section C-Final Project

RULES:

-Use the mouse (either by pressing or moving around) to interact with animations

-Click any key to cycle through different animations (click within the canvas first if not working because wordpress is weird)

Note: If file is opened through google browser, mouse isn’t limited on first animation and they all generally run smoother

sketch

//Ashley Chan
//Section C
//ashleyc1@andrew.cmu.edu
//Final Project - Type in Motion

/////////////////////////////////////
// MAIN  CONTROL //
///////////////////////////////////

var index = 0;

//global var for images
var revealImg;
var twinkleImg;
var eraseImg;
var sprayHintImage;
var sprayOverlayImage;

function preload() {

//load all the images
revealImg = loadImage("https://i.Imgur.com/giFSIcI.jpg?1");
twinkleImg = loadImage("https://i.imgur.com/hqn6Cv9.jpg?1");
eraseImg = loadImage("https://i.imgur.com/VO4buSz.png");
sprayHintImage = loadImage("https://i.imgur.com/P6LkUET.jpg");
sprayOverlayImage = loadImage("https://i.imgur.com/dr6JWoH.png");

}

function setup() {

    createCanvas(480, 180);
    background(0);

    //index that cycles through animations
    //call each animations' setups 
    //depending on index number
    if(index == 0){
        revealSetup();
    }

    if(index == 1){
        twinkleSetup();
    }

    if(index == 2){
        eraseSetup();
    }

    if(index == 3){
        spraySetup();
    }
}


function draw() {

    //call each animations' draw depending on index number
    if(index == 0) {
        revealDraw();
    }

    if(index == 1){
        twinkleDraw();
    }

    if(index == 2){
        eraseDraw();
    }

    if(index == 3){
        sprayDraw();
    }

}

// Cycles through animations every time 
//any key is pressed
function keyPressed(){

    index = (index + 1)%4;

    setup();

}

////////////////////////////////////////////
// REVEAL  ANIMATION //
///////////////////////////////////////////

//var that will spell out reveal
var revealCircles; 
var revealDots;


function revealSetup(){
    
    //Draw a black rectangle for every animation 
    //because we need to make sure the animations 
    //restart without actually calling setup 
    //and messing everything up
    fill(0);
    rect(0, 0, 480, 180);

    revealCircles = [];
    revealDots = [];

    // iterate through pixels
    image(revealImg, 0, 100);
    revealImg.loadPixels();
    
    for(var i = 0; i < 2 * revealImg.width; i++) {
        for(var j = 0; j < revealImg.height; j++) {

            var revealIndex = i * 2 + (j * revealImg.width)*8;
            
            //locate the dark pixels of underlaying image
            //where there is dark, make a revealCircle
            if (revealImg.pixels[revealIndex] < 200){

                revealDots.push(createVector( i / 2, j * 2));
            }
        }
    }

        var num_circles = 0;
    
    //draw certain number of revealCircles every frame
    while (num_circles < 400){
        
        var c = revealCreateCircle();
    
        if (c) {

            revealCircles.push(c);
            num_circles++;

        }
    }
}


function revealDraw(){

    background(0);
  
    //draw the revealCircles
    for(var i = 0; i < revealCircles.length; i++) {
      
        var x = revealCircles[i].x;
        var y = revealCircles[i].y;
        var r = revealCircles[i].r;

    //calculate distance around mouse
    //any space within radius will be drawn and shown
    var d = dist(x, y, mouseX, mouseY);

    if (d  < 90) {
        //center image
        push();
        scale(.5, .5);
        translate(150, 0);
        revealCircles[i].show();
        pop();

        }
    }
}

//While creating a new revealCircle
//Do not create one inside existing one
function revealCreateCircle(){

    var x;
    var y;
    
    // find a random position to create a revealCircle
    var position = int(random(0, revealDots.length));

    x = revealDots[position].x;
    y = revealDots[position].y;

    var valid = true;

    for (var i = 0; i < revealCircles.length; i++) {

        //Don't draw inside another revealCircle
        // If generated already drawn revealCircle, redo
        if (dist(x, y, revealCircles[i].x, revealCircles[i].y) <= revealCircles[i].r) {

            valid = false;
            break;
        }
    }

    //if no revealCircle drawn at spot, draw one 
    if (valid) {

        return new revealCircle(x, y, width, height);
    }

    return false;
}

//define the circles
function revealCircle(xPos, yPos, gwidth, gheight){

    this.x = xPos;
    this.y = yPos;
    this.r = 8;

    this.width = gwidth;
    this.height = gheight;

    //controls the look of the revealCircles 
    //randomizes color when mouse is pressed
    this.show = function(){

        fill(255);
        noStroke();
        strokeWeight(1);
        ellipse(this.x, this.y, this.r);

        }
}


////////////////////////////////////////////////
//  TWINKLE   ANIMATION //
///////////////////////////////////////////////

//var that will spell out twinkle
var twinkleCircles;
var twinkleDots;


function twinkleSetup(){
    
    fill(0);
    rect(0, 0, 480, 180);

    twinkleCircles = [];
    twinkleDots = [];
    
    // iterate through pixels
    //image(twinkleImg, 0, 100);
    twinkleImg.loadPixels();
    
    //locate the dark pixels of underlaying image
    //where there is dark, make a twinkleCircle
    for(var i = 0; i < 2 * twinkleImg.width; i++) {
        for(var j = 0; j < twinkleImg.height; j++) {

            var twinkleIndex = i * 2 + (j * twinkleImg.width)*8;
            
            if (twinkleImg.pixels[twinkleIndex] < 200){

                twinkleDots.push(createVector( i / 2, j * 2));
            }
        }
    }

    var num_circles = 0;
    
    //draw certain number of twinkleCircles every frame
    while (num_circles < 300){
        
        var c = twinkleCreateCircle();

        if (c) {

            twinkleCircles.push(c);
            num_circles++;

        }

    }
    
    //draw the twinkleCircles
    for(var i = 0; i < twinkleCircles.length; i++) {
      
        var x = twinkleCircles[i].x;
        var y = twinkleCircles[i].y;
        var r = twinkleCircles[i].r;

        //center image
        push();
        scale(.6, .6);
        translate(50, 80);
        twinkleCircles[i].show();
        pop();
        
    }
}


function twinkleDraw(){

    //if mouse pressed, "redraw" circles
    //so that color is randomized
    if(mouseIsPressed) {
        for(var i = 0; i < twinkleCircles.length; i++) {
      
            var x = twinkleCircles[i].x;
            var y = twinkleCircles[i].y;
            var r = twinkleCircles[i].r;

            //center image
            push();
            scale(.6, .6);
            translate(50, 80);
            twinkleCircles[i].show();
            pop();

        }
    }
}

//While creating a new twinkleCircle
//Do not create one inside existing one
function twinkleCreateCircle(){

    var x;
    var y;
    
    // find a random position to create a twinkleCircle
    var position = int(random(0, twinkleDots.length));

    x = twinkleDots[position].x;
    y = twinkleDots[position].y;

    var valid = true;

    for (var i = 0; i < twinkleCircles.length; i++) {

        //Don't draw inside another twinkleCircle
        // If generate already drawn twinkleCircle, redo
        if (dist(x, y, twinkleCircles[i].x, twinkleCircles[i].y) <= twinkleCircles[i].r) {

            valid = false;
            break;
        }
    }

    //if no twinkleCircle drawn at spot, draw one 
    if (valid) {

        return new twinkleCircle(x, y, width, height);
    }

    return false;
}

//define twinkleCircles
function twinkleCircle(xPos, yPos, gwidth, gheight){

    this.x = xPos;
    this.y = yPos;
    this.r = 8;

    this.width = gwidth;
    this.height = gheight;

    //controls the look of the twinkleCircles 
    //randomizes color when mouse is pressed
    this.show = function(){

        stroke(255);
        strokeWeight(1);

        //start out as empty twinkleCircles
        var value = 0;
        fill(value);

        //change the color every time mouse is pressed
        if (mouseIsPressed) {

        value = random(0, 255);

        fill(value, value, value);

        }

        ellipse(this.x, this.y, this.r);

        }
}


////////////////////////////////////////////
// ERASE  ANIMTATION //
///////////////////////////////////////////

//var for erase animation
var eraseLastMinute;
var eraseCurrentMinute;

//eraseIndex for animations
var eraseIndex = 0;


function eraseSetup() {
    //scale(.5, .5);
    
    fill(0);
    rect(0, 0, 480, 180);
    eraseImg.loadPixels();

    eraseLastMinute = minute();
    
    //make for loop to control how many images we are making
    for (i = 0; i < 50; i++) {

        image(eraseImg, random(-50, 800), 
            random(-50, height), 100, 43);

    }
}

function eraseDraw() {

    fill(0);
    noStroke();
    ellipse(mouseX, mouseY, 30, 30);

    //call setup and reset every minute
    eraseCurrentMinute = minute();

    //if a minute has passed, call setup and generate 
    //different arrangement of words
    if (eraseLastMinute != eraseCurrentMinute) {

    eraseSetup();

    }
}

///////////////////////////////////////////
//  SPRAY  ANIMATION //
//////////////////////////////////////////

var sprayDots; 

function spraySetup() {

    fill(0);
    rect(0, 0, 480, 180);
    noCursor();   
    noStroke();   
  
    sprayDots = [];

}

function sprayDraw() {

    image(sprayHintImage, 50, 100);
    sprayHintImage.resize(300, 100);

    background(0);
  
    var position = createVector(mouseX, mouseY);

    //if mouse is pressed, draw a bunch of sprayCircles
    //that move toward the overlaying image
    if (mouseIsPressed) {
    var target = sprayFindPixel();    
    var spraydot = new sprayDot(position, target);

    sprayDots.push(spraydot);

    //allow user to draw a bunch of dots
    if (sprayDots.length > 2000) sprayDots.shift();    

    }  
          //draws the sprayDots
          for (var i = 0; i < sprayDots.length; i++) {

            //make sure sprayDots align with hint image
            push();
            translate(100, 50);
            sprayDots[i].update();
            sprayDots[i].draw();
            pop();

        }   

            //call image of Spray outline
            image(sprayOverlayImage, 100, 50);
            sprayOverlayImage.resize(300, 100);
}

//calculate where the underlying image is dark
//and then draw a spraydot overtop
function sprayFindPixel() {

var x;
var y;

    for (var i = 0; i < 200; i++) {

        x = floor(random(sprayHintImage.width));
        y = floor(random(sprayHintImage.height));
    
        if (red(sprayHintImage.get(x, y)) < 255) break;

  }

  return createVector(x, y);

}

//create sprayDots and define characteristics
function sprayDot(position, target) {

    this.position = position;
    this.target = target;
    this.diameter = random(10, 20);

}

sprayDot.prototype.update = function() {   
  
    this.position = 
    p5.Vector.lerp(this.position, this.target, 0.1);

};

sprayDot.prototype.draw = function() { 
  
    //color of sprayDots
    fill(255);
    ellipse(this.position.x, this.position.y, this.diameter, this.diameter);

};


For this project, I was interested in creating interactive animations that allowed type to be dynamic. I wanted the user to interact with the text based on the actions the words described (erase = erase the words). This project was super challenging and I wish I had more time to generate more interactive animations but I’m overall satisfied with it because I like exploring how to make type more dynamic that I can now use within my own art and design practice.

ashleyc1-Section C-LookingOutwards-12

Mind & Matter 3
Mind & Matter 2
Mind & Matter 1
Slanted Magazine #15 Experimental

The first project that really inspired my final project is Mind and Matter by LIA, a software and net artist who creates abstract, generative images using code. Her designs have been used for apps, performance, sculpture, projections and graphic print. She is mostly interested in the relationship of machine as artist and artist as machine: viewing the interaction as both a dependence but also conversation. All of her work is beautiful and incredible.

Her project Mind and Matter is a typographical image of the phrase Mind & Matter that is spelled out by ellipses and lines but deteriorate and evolve into a more chaotic pattern. This was finalized as a 2D image for the daily Austrian newspaper diePresse: “Freiraum” and in Slanted Magazine #15 Experimental.

Source:

Mind and Matter

 

 

 

 

New York Times 1
New York Times 2
New York Times 3

The second artist who inspired my project is Kate Hollenbach – an artist and programmer who explores interactive systems and new technologies to redefine the relationships between body, gesture and physical space. I was mostly attracted to her New York Times piece where she deconstructed the text on the New York Times using a photocopier.

Although this piece was more a formal exercise and not much compared to her more newer, more sophisticated pieces, I was still mesmerized by the layering of text to build into larger letters and altering text so that it was manipulated around larger images. I also like the idea of hacking a photocopier to play with typography and layout.

Source:

http://www.katehollenbach.com/new-york-times/

ashleyc1-Section C-Final-Project-Proposal

Very basic sketch

For my final project I want to explore the relationship between typography and animation. I want to create an interactive, animated text so that the movement reflects the word. I noticed that p5 has reference functions to allow local servers to be hosted on one’s phone: allowing the phone to essentially be a controller. This project will probably include animated illustrations but I want to push myself to animate just text so that they move in a way that’s still communicative without outside images. I’m not sure how many different text animations I should have but ideally, they would be cycling through an array the more the participant interacted with it.

ashleyc1-Section C-Project-11-Composition

sketch

//Ashley Chan
//Section C
//ashleyc1@andrew.cmu.edu
//Assignment-10-B

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;

}

//rainbow shape
function makeShape(turtle) {

    //make one hexagon
    for(i = 0; i < 6; i++) {

        //rainbow colors
        var r = random(100, 255);
        var g = random(100, 255);
        var b = random(100, 255);
      

        turtle.setColor(color(r, g, b));
        turtle.setWeight(1);

        turtle.forward(50);
        turtle.left(60);

    }
}

//cream shape
function makeShape2(turtle2) {

    //make one shape
    for(i = 0; i < 8; i++) {

        turtle2.setColor(color(249, 237, 217));
        turtle2.setWeight(2);

        turtle2.forward(60);
        turtle2.left(80);

    }
}

//perriwinkle shape
function makeShape3(turtle3) {

    for(i = 0; i < 8; i++) {

        turtle3.setColor(color(172, 195, 249));
        turtle3.setWeight(1);

        turtle3.forward(60);
        turtle3.left(100);

    }
}


function setup() {
    createCanvas(480, 480);
    background(0);

     //name spiral motion
    var spiral = makeTurtle(200, 170);
    var shape2 = makeTurtle(320, 300);
    var shape3 = makeTurtle(120, 420);

    var angle = random(60, 140)
    var positionX = 0;

      //make a bunch of repeating shapes
      for(var i = 0; i < 80; i++) {

          makeShape(spiral);

          spiral.penUp();
          spiral.right(angle);
          spiral.forward(positionX);

          //draw again
          spiral.penDown();

          //increase space inbetween initial shapes the more you draw them
          positionX += 1; 
      
      }

      for(var j = 0; j < 10; j++) {

          makeShape2(shape2);

          shape2.penUp();
          shape2.right(angle);
          shape2.forward(6);
          shape2.penDown();
          }
      
        for (var k = 0; k < 80; k++ ) {
          makeShape3(shape3);

          shape3.penUp();
          shape3.right(angle * .5);
          shape3.forward(6);
          shape3.penDown();
          }
}

function draw() {

}

function mouseClicked() {

  setup();

}

I really like making spirographs. As a kid I doodled them all the time and a lot of the projects I’ve done for this class include spirographs but I like that I’m learning how to draw them through different techniques: this week via turtle graphics.

Slight alterations to the spirographs’ angles and spaces are changed when the mouse is clicked.

Iterations:

ashleyc1-LookingOutwards-11

WE is an interactive, immersive sound installation by the studio Let’s and specifically designed and programmed by Andy Arkley, Peter Lynch, and Courtney Barnebey. First exhibited in Seattle’s MadArt event, WE’s creators wanted to create a place where a shared community and experience could be built-moving beyond people interacting with the piece but also with each other. The project allows for up to 12 participants where they can interact with controllers to create musical sequences. The installation used light bulbs, music, and mapped video projections to synchronize with the music and create an overwhelming, sensual experience. What makes this interactive sound installation unique from others is that this machine doesn’t stay silent when there aren’t any participants; making it more initially inviting to participants. Any one can also start interacting with the controllers and feel like they’re not messing up any previously established sound because the musical sequences aligned to the controllers are programmed to synchronize with each other. So even though participants have choice in what to play, all of the sounds still work well together. I think this feature is what makes this piece particularly successful.

Sources:

https://creators.vice.com/en_us/article/vvaeja/you-can-play-these-giant-sculptures-like-musical-instruments

http://letspresents.com/wewe/

ashleyc1-Section C-Project-10-Landscape

sketch

//Ashley Chan
//Section C
//ashleyc1@andrew.cmu.edu
//Project-10-Landscape

var flowers = [];

var boatX = 440;
var boatY = 280;
var floatHeight;


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

    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){

        var rx = random(width);
        var ry = random(height);

        flowers[i] = makeFlower(rx, ry);
    }

    frameRate(10);

}
 
function draw() {
    background(252, 220, 255);

    drawMountains();
    drawWater();
    drawBoat();

    
    displayHorizon();

    updateAndDisplayFlowers();
    removeFlowersThatHaveSlippedOutOfView();
    addNewFlowersWithSomeRandomProbability(); 

    
}

function updateAndDisplayFlowers(){
    // Update the flower's positions, and display them.
    for (var i = 0; i < flowers.length; i++){

        flowers[i].move();
        flowers[i].display();
    }
}

function removeFlowersThatHaveSlippedOutOfView(){

    var flowersToKeep = [];
    
    for (var i = 0; i < flowers.length; i++){

        if (flowers[i].x + flowers[i].stemThickness > 0) {

            flowersToKeep.push(flowers[i]);
        
        }
    }

    flowers = flowersToKeep; // remember the surviving flowers
}


function addNewFlowersWithSomeRandomProbability() {

    // With a very tiny probability, add a new flower to the end.
    var newFlowerLikelihood = 0.01; 

    if (random(0,1) < newFlowerLikelihood) {

        flowers.push(makeFlower(width));
    }
}


// method to update position of flower every frame
function flowerMove() {
    this.x += this.speed;
    this.y += this.speed;

}
    

// draw the flower and some windows
function flowerDisplay() {

    var floorHeight = -5;
    var stemHeight = this.nFloors * floorHeight; 

    push();
    translate(this.x, height - this.offset);
    
    //draw stems
       fill(210);
       rect(0, 0, this.stemThickness, stemHeight);

       translate(this.stemThickness/2, stemHeight);
        //draw flowers here
        for (var i = 0; i < 100; i++) {

            var g = random(0, 100);
            var b = random(0, 100);

            noStroke();
            fill(206, g, b);
            ellipse(0 , 10, 5, 30);
            rotate(PI/5);

            } 

    pop();
}


function makeFlower(birthLocationX, birthLocationY) {
    var flwr = {x: birthLocationX, 
                y: birthLocationY,
                floatHeight: random(10, 100),
                stemThickness: 5,
                speed: -1.0,
                nFloors: round(random(5, 10)),
                offset: random(10, 40), //allows stems to be drawn at various points
                move: flowerMove,
                display: flowerDisplay}

    return flwr;
}

//horizon that flowers are on
function displayHorizon(){
    noStroke(0);
    fill(81, 64, 137);
    rect(0, height - 100, width, height - 100); 
}


function drawWater() {

    var waterSpeed = 0.00009;
    var waterDetail = 0.0005;

    beginShape(); 

    fill(209, 211, 255);
    noStroke();
   
    for (var xWater = 0; xWater < width; xWater++) {

        var tWater = (xWater * waterDetail) + (millis() * waterSpeed);
        var yWater = map(noise(tWater), 0,1, 180, 280);
        vertex(xWater, yWater); 

        //make it draw to edge of canvas
        vertex(0, height);
        vertex(width, height);

    }

    endShape();

}

function drawMountains() {

    var mountainSpeed = 0.0005;
    var mountainDetail = 0.008;

    //Background Mountains
    beginShape(); 

    fill(101, 101, 202, 150);
    noStroke();
   
    for (var xMount = 0; xMount < width; xMount++) {

        var tMount = (xMount * mountainDetail) + (millis() * mountainSpeed);
        var yMount = map(noise(tMount), 0,1, 20, 100);
        vertex(xMount, yMount); 
        vertex(0, height);
        vertex(width, height);


    }

    //foreground mountains
    endShape();
    beginShape(); 

    fill(204, 204, 255, 150);
    noStroke();
   
    for (var xMount = 0; xMount < width; xMount++) {

        var tMount = (xMount * mountainDetail) + (millis() * mountainSpeed);
        var yMount = map(noise(tMount), 0,1, 80, 180);
        vertex(xMount, yMount); 
        vertex(0, height);
        vertex(width, height);

        //stagger mountain edges
        mountainDetail = .01;
    }

    endShape();

}


function drawBoat() {

    //post and sail
    stroke(255);
    strokeWeight(2);
    fill(255);
    line(boatX, boatY, boatX, boatY - 50);
    triangle(boatX, boatY - 50, boatX + 30, boatY -10, boatX, boatY - 5);

    fill(153, 51, 0);
    noStroke();
    arc(boatX, boatY, 80, 50, TWO_PI, PI);

    boatX -= 1;

    //var constrainY = constrain(boatY, 180, 280); 

    //reset boatX so it can repeat when it goes over edge of canvas
    if (boatX < -40) {

        boatX = width;
    }
}

For this project, I wanted to create a mountainscape because I find those peaceful to look at especially when going through the terrible stress of school in general. My image probably could’ve been pushed further but I had a lot of difficulty understanding what characteristics could automatically be defined within an objet and how those elements interacted with one another so just getting my landscape to this point was a success for me.

 


//Ashley Chan
//Section C
//ashleyc1@andrew.cmu.edu
//Project-10-Landscape

var flowers = [];

var boatX = 440;
var boatY = 280;
var floatHeight;


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

    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){

        var rx = random(width);
        var ry = random(height);

        flowers[i] = makeFlower(rx, ry);
    }

    frameRate(10);

}
 
function draw() {
    background(252, 220, 255);

    drawMountains();
    drawWater();
    drawBoat();

    
    displayHorizon();

    updateAndDisplayFlowers();
    removeFlowersThatHaveSlippedOutOfView();
    addNewFlowersWithSomeRandomProbability(); 

    
}

function updateAndDisplayFlowers(){
    // Update the flower's positions, and display them.
    for (var i = 0; i < flowers.length; i++){

        flowers[i].move();
        flowers[i].display();
    }
}

function removeFlowersThatHaveSlippedOutOfView(){

    var flowersToKeep = [];
    
    for (var i = 0; i < flowers.length; i++){

        if (flowers[i].x + flowers[i].stemThickness > 0) {

            flowersToKeep.push(flowers[i]);
        
        }
    }

    flowers = flowersToKeep; // remember the surviving flowers
}


function addNewFlowersWithSomeRandomProbability() {

    // With a very tiny probability, add a new flower to the end.
    var newFlowerLikelihood = 0.01; 

    if (random(0,1) < newFlowerLikelihood) {

        flowers.push(makeFlower(width));
    }
}


// method to update position of flower every frame
function flowerMove() {
    this.x += this.speed;
    this.y += this.speed;

}
    

// draw the flower and some windows
function flowerDisplay() {

    var floorHeight = -5;
    var stemHeight = this.nFloors * floorHeight; 

    push();
    translate(this.x, height - this.offset);
    
    //draw stems
       fill(210);
       rect(0, 0, this.stemThickness, stemHeight);

       translate(this.stemThickness/2, stemHeight);
        //draw flowers here
        for (var i = 0; i < 100; i++) {

            var g = random(0, 100);
            var b = random(0, 100);

            noStroke();
            fill(206, g, b);
            ellipse(0 , 10, 5, 30);
            rotate(PI/5);

            } 

    pop();
}


function makeFlower(birthLocationX, birthLocationY) {
    var flwr = {x: birthLocationX, 
                y: birthLocationY,
                floatHeight: random(10, 100),
                stemThickness: 5,
                speed: -1.0,
                nFloors: round(random(5, 10)),
                offset: random(10, 40), //allows stems to be drawn at various points
                move: flowerMove,
                display: flowerDisplay}

    return flwr;
}

//horizon that flowers are on
function displayHorizon(){
    noStroke(0);
    fill(81, 64, 137);
    rect(0, height - 100, width, height - 100); 
}


function drawWater() {

    var waterSpeed = 0.00009;
    var waterDetail = 0.0005;

    beginShape(); 

    fill(209, 211, 255);
    noStroke();
   
    for (var xWater = 0; xWater < width; xWater++) {

        var tWater = (xWater * waterDetail) + (millis() * waterSpeed);
        var yWater = map(noise(tWater), 0,1, 180, 280);
        vertex(xWater, yWater); 

        //make it draw to edge of canvas
        vertex(0, height);
        vertex(width, height);

    }

    endShape();

}

function drawMountains() {

    var mountainSpeed = 0.0005;
    var mountainDetail = 0.008;

    //Background Mountains
    beginShape(); 

    fill(101, 101, 202, 150);
    noStroke();
   
    for (var xMount = 0; xMount < width; xMount++) {

        var tMount = (xMount * mountainDetail) + (millis() * mountainSpeed);
        var yMount = map(noise(tMount), 0,1, 20, 100);
        vertex(xMount, yMount); 
        vertex(0, height);
        vertex(width, height);


    }

    //foreground mountains
    endShape();
    beginShape(); 

    fill(204, 204, 255, 150);
    noStroke();
   
    for (var xMount = 0; xMount < width; xMount++) {

        var tMount = (xMount * mountainDetail) + (millis() * mountainSpeed);
        var yMount = map(noise(tMount), 0,1, 80, 180);
        vertex(xMount, yMount); 
        vertex(0, height);
        vertex(width, height);

        //stagger mountain edges
        mountainDetail = .01;
    }

    endShape();

}


function drawBoat() {

    //post and sail
    stroke(255);
    strokeWeight(2);
    fill(255);
    line(boatX, boatY, boatX, boatY - 50);
    triangle(boatX, boatY - 50, boatX + 30, boatY -10, boatX, boatY - 5);

    fill(153, 51, 0);
    noStroke();
    arc(boatX, boatY, 80, 50, TWO_PI, PI);

    boatX -= 1;

    //var constrainY = constrain(boatY, 180, 280); 

    //reset boatX so it can repeat when it goes over edge of canvas
    if (boatX < -40) {

        boatX = width;
    }
}

 

ashleyc1-Section C-LookingOutwards-10

Rachel Rossin
Lossy

Rachel Rossin’s work is a multi-media, installation artist based in New York City. Her exhibition Lossy, is an investigation of the limitations of VR especially in a physical realm. She takes pre-created images and scans and alters them via VR functions and photogrammetry – creating infinite VR worlds that viewers can explore beyond her paintings. She then creates large oil paintings from these altered images within the VR world. I think this recycling process of taking reality and altering then putting back into reality is very cool. During her artist talk at the VR convention in Pittsburgh last year, Rossin says that she’s just trying to make sense of VR through painting and it’s just there to be a physical encapsulation. But I think there’s more because there is the complexity about translating something physical to virtual to physical again.

Gif animation of her contributing work for the VR salon in Pittsburgh

Maybe it’s a commentary about perceived reality, or maybe it’s about entropy, though Rossin denied it during the presentation. Her piece at the VR salon, a floating wreck composed of juxtaposed scenes from her life, felt ethereal as one floated around; something I find present in her translated paintings. Since she is a rather young artist, I’m interested to see how she develops and whether or not she decides to venture in recreating the digital world through other mediums besides painting.

Sources:

http://ziehersmith.com/exhibition/139/lossy

rossin.co/

Rachel Rossin’s Trippy Paintings of Reality as Seen Through VR

 

ashleyc1-SectionC-Project-09-Portrait

sketch

//Ashley Chan
//Section C
//ashleyc1@andrew.cmu.edu
// Project-09-Portrait

var portrait;

var particles = []; 


function preload () {
    var portraitURL = "https://i.imgur.com/ZaGPL9g.jpg?7";
    portrait = loadImage(portraitURL);

}


function setup() {
   createCanvas(230, 300);
    frameRate(10);

    //draw a cloud of particles that will draw face
    for (var i = 0; i < 200; i++) {

        //drawing a bunch of new particles and having them start at random origins
        particles[i] = new Particle(random(width), random(height));

    }

    background(210);

}

function draw() {
    //image(portrait, 0, 0);
   portrait.loadPixels();

       //draw a bunch of pixels
       for (var i = 0; i < particles.length; i++) {
            particles[i].update();
            particles[i].show();
        }
}


//define the pixel particles
function Particle(x, y) {

    //controls positions
    this.x = x;
    this.y = y;
    //controls sizes of ellipses
    this.r = random(1, 10);

    //new pixel particles drawn in random directions within 5 pixel radius
    this.update = function() {
        this.x += random(-5, 5);
        this.y += random(-5, 5);
    }

    //physical appearence of pixel particles and associated constraints
    this.show = function() {
        //setting parameters to draw using color of pixels in image
        var ix = constrain(floor(this.x), 0, width-1);
        var iy = constrain(floor(this.y), 0, height-1);
        var col = portrait.get(ix, iy);

        //getting the pixel particle to draw using color of pixels in image
        noStroke();
        fill(col[0], col[1], col[2]);
        rect(this.x, this.y, this.r, this.r);

        //sets default forces to pixel particles to mimic brush strokes 
        //rather than random pointalism
        var pxv = random(-1, 1); //velocity of x
        var pyv = random(-1, 1); //velocity of y
        var drag = 1; //force that pushes in opposite direction of velocity

        //applies forces
        this.x += pxv;
        this.y += pyv;

         pxv -= pxv * pxv * drag;
         pyv -= pyv * pyv * drag;

        //if pixel particles exceeds canvas height, reset to origin
        if (this.y > height) {

            this.x = 0;
            this.y = 0;

            }
        }
    }

For this project I was really inspired by Dan Shiffman’s Painting with Pixels video where you can recapture videos by using a painterly effect to replicate the image. To make it my own creation, I applied what we learned in lecture about forces to manipulate the pixels to “paint” with specific directions, sizes and motions.

Here are some process shots:

ashleyc1-Section C- Looking Outwards-09

Marius Watz’s Arcs04-00
Marius Watz’s Arcs04-01

I was really inspired by Hae Wan Park’s post from week 6 about Marius Watz and Jer Thorp’s collaboration for the Random Number Multiples Series curated by Christina Vassallo. This project was a computational collection in which Watz and Thorp created a program that would track how many times a specific word was used throughout the New York Times and visually display that information in cyclic shapes with lots of bold, layered colors. What is special about this project is that the final design was a screen printed poster.

The ‘Arc’ Series – Process of Screen Printing

I agree with Hae Wan that this project is interesting mainly because it’s a combination of computational information design and the traditional process of screen printing. I’d go further to explain that this relationship is needed because the conceptual inspiration came from physical newspapers and to reprint this information into a new physical form elevates the project to thinking not only about societal themes but also how we take in information today.

Jer Thorp’s Hope/Crisis

I disagree with Hae Wan when they say that this is just artistic expression. This process is unique because there’s this relationship to taking something digital and making it tangible and physical but I think Hae Wan should have talked more about the conceptual thinking behind the project because it does have some political undertones to it. For example, Je Thorp’s piece Hope/Crisis tracks how much the NY Times printed the words Hope and Crisis which is overwhelming just to see in amount but also makes you realize that we use the word hope more than crisis and has a sentimental reflection that despite living with current and recent devastations, humans still remain hopeful of a better future-something that’s conceptually interesting and equal to the unique process of creating this project.

Sources:

https://creators.vice.com/en_us/article/vvzxkb/random-numbers-screen-printed-generative-art-nyc-event

https://creators.vice.com/en_us/article/4x47bw/overcoming-manual-inadequacy-an-interview-with-marius-watz

What is Random Number?

http://blog.blprnt.com/blog/blprnt/random-number-multiples

ashleyc1-Section C-Looking Outwards-08

Eyeo 2016 – Paolo Ciuccarelli

Paolo Ciuccarelli is part of a research design group, DensityDesign, in conjunction with a university in Italy. At Eyeo, Ciuccarelli talked about The Poetics of Data Experiences: how to visualize big data that displays the information that is expressive of time, space and emotion. Ciuccarelli uses the term info-poetry to teach that design should play with rhetoric and emotion, ensure the meaning of the message is understandable, make it reproducible and potentially open source it. He shows several examples of his student’s work where they essentially create projects that encapsulate data reflective of contemporary society and present it in a manner that follows the main info-design principles. It’s a step upward from a regular infographic; visually representing data in a way that will elicit emotion. I was drawn to example projects that really utilized media to express data as it was stronger than just using a computer to create a generative body.

Crumpled Italia

There was a project called Crumpled Italia where pieces of paper are displayed in a grid to represent different countries. Each piece of paper was crumbled to a percentage that matched the statistic of domestic abuse in the country. I found that piece extremely profound as it really elicits empathy without being exposed to a “gory” image which is what info-poetry is about. I find the general topic of representing and visualizing data fascinating. Ciuccarelli explains that he was fascinated with understanding complex systems and using data visualization to make sense of them as well as teach to others. As a person, I share that same fascination and would be interested in learning how to fuse generative computer graphics and tangible materials with design.

Essentially, his form of presenting data is the same in which he enjoys using graphics to communicate ideas and numbers but rendering them in such a way that the viewer experiences an emotional response. I noticed a lot of the times, the viewer is responding to abundance of data but the data is also elevated by variables such as color and music. This is a good example for myself to reference when thinking about how presentation and documentation of information should display not only the data itself but the context, mood and tone of the data.