Eunice Choe – Final Project

sketch

/*Eunice Choe
Section E
ejchoe@andrew.cmu.edu
Final Project*/

// options variable
var option = 1;

// scene 1
var Px = [];
var Py = [];
var Pdx = [];
var Pdy = [];
var newP = [];

// scene 2
var r = 220;
var g = 247;
var b = 255;
var cloud = [];
var landscape = 0.002;
var spot = [];
var flowers = [];

// scene 3
var img;

// spring constants (blinds pulling bar)
var springHeight = 32;
var left;
var right;
var maxHeight = 100;
var minHeight = 200;
var over = false;
var move = false;

// spring constants (main blinds)
var mass = 0.8;
var sConstant = 0.2;
var damping = 0.92;
var rest = 40;

// spring movement variables
var ps = rest;   // position
var vs = 0.0; // velocity
var as = 0;   // acceleration
var f = 0;    // force

//scene 4
var img4;
var input;
var analyzer;


function preload() {
    img = loadImage("https://i.imgur.com/IdD3GJq.png");
    img4 = loadImage("https://i.imgur.com/sR307j6.png?2");
}

function setup(){
    createCanvas(480, 300);
// initializing floating particles
    for (i = 0; i < 100; i++) {
        Px[i] = random(480);
        Py[i] = random(300);
        Pdx[i] = random(-5, 5);
        Pdy[i] = random(-5, 5);
    }
    frameRate(10);

    push();
    angleMode(DEGREES);
    // initial collection of flowers and clouds
    for (var i = 0; i < 10; i++) {
        var cloudX = random(width);
        var rx = random(width);
        cloud[i] = makeCloud(cloudX);
        flowers[i] = makeFlowers(rx);
    }

// initializing lefts and rights for spring
    left = width/2 - 150;
    right = width/2 + 150;

// initializing audio input
    input = new p5.AudioIn();
    input.start();
}

function draw() {
    background(220, 247, 255);
    noStroke();
// scene 1
    if (option == 1){
        scene1();
    }
// scene 2
    else if (option == 2) {
        scene2();
    }
// scene 3
    else if (option == 3) {
        scene3();
    }
// scene 4
    else if (option == 4) {
        scene4();
    }
}

function scene1() {
    translate(width / 2, height / 2);
// flower petals
    for (var i = 0; i < 20; i ++) {
        fill(255, 224, 122, 90);
        ellipse(0, 30, 100, 500);
        rotate(PI * 8);
  }
// flower center
    for (var i = 0; i < 10; i ++) {
        fill(84, 46, 13, 80);
        ellipse(0, 0, 100, 200);
        rotate(PI * 8);
  }
// floating particles
    for (i = 0; i < 500; i++) {
        fill(255, 90);
        ellipse(Px[i], Py[i], 10, 10);
        Px[i] += Pdx[i];
        Py[i] += Pdy[i];
    }
}

function scene2(){
    background(r, g, b);
    if (mouseX > 0 & mouseX < width) {
        r = 229 - mouseX / 20;
        g = 247 - mouseX / 50;
        b = 224 + mouseX / 20;
    }
// grass in the back; randomizes when page refreshed
    beginShape();
    fill(139, 189, 125);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = x * landscape;
        var y = map(noise(t), 0, 1, 0, height / 2);
        vertex(x, y + 100);
    }
    vertex(width, height);
    endShape();
    updateFlowers();
// rain when mouse is pressed
    if (mouseIsPressed) {
        frameRate(90);
        fill(255);
        spot.x = random(width);
        spot.y = random(height);
        ellipse(spot.x, spot.y, 5, 70);
    }
// clouds
    for (var i = 0; i < cloud.length; i++) {
        cloud[i].draw();
        cloud[i].move();
    }
}

function scene3() {
    image(img, 0, 0);
    fill(156, 38, 27);
    rect(0, 0, 100, height);
    rect(380, 0, 100, height);
    rect(100, 0, 280, 40);
    rect(100, 260, 280, 40);
    fill(242, 235, 202);
    rect(90, 270, 300, 10);
    fill(201, 196, 168);
    quad(100, 260, 380, 260, 390, 270, 90, 270);
    stroke(74, 89, 79);
    noFill();
    strokeWeight(10);
// sky gets darker when mouse is in window
    if ((mouseX > 100) & (mouseX < 380) &&
        (mouseY > 40) && (mouseY < 260)) {
        fill(43, 29, 133, 50);
    }
    rect(100, 40, 280, 220);
    updateSpring();
    drawSpring();
}

function scene4() {
    image(img4, 0, 0);
    push();
    var volume = input.getLevel();
// if the volume of the sound goes above threshold, then a firefly will appear
// fireflies are at random positions and their sizes reflect the volume
    var threshold = 0.05;
    if (volume > threshold) {
        push();
        frameRate(10);
        noStroke();
        fill(199, 255, 57);
        ellipse(random(width), random(170, height), volume * 50, volume * 50);
        pop();
    }
    fill(161, 156, 125);
    rect(40, 120, 60, 145);
    pop();
}

function updateFlowers() {
    // Update the flowers positions; random when page refreshed
    for (var i = 0; i < flowers.length; i++){
        flowers[i].display();
    }
}

function flowersDisplay() {
    var floorHeight = 10;
    var bHeight = this.nFloors * floorHeight * 2;
    noStroke();
    push();
    translate(this.x, height);
    fill(204, 187, 145);
    rect(0, -bHeight, this.breadth, bHeight);
    noStroke();
    translate(0, -bHeight);
    for (var i = 0; i < 20; i ++) {
        fill(255, 224, 122, 90);
        ellipse(0, 30, 20, 50);
        rotate(PI * 8);
    }
    fill(84, 46, 13, 90);
    ellipse(0, 0, 30, 30);
    pop();

}

function makeFlowers(birthLocationX) {
    var fl = {x: birthLocationX,
             breadth: 5,
             nFloors: round(random(2,8)),
             display: flowersDisplay}
    return fl;
}

function cloudDraw() {
    push();
    translate(this.xPos, this.yOffset);
    stroke(255, 255, 255, 70);
    strokeWeight(this.cHeight);
    line(0, 0, this.cSize, 0);
    pop();
}

function cloudMove() {
    this.xPos += this.speed;
    if(this.xPos < 0 - this.cSize - 30) {
        this.cHeight = random(10, 50);
        this.cSize = random(30, 150);
        this.xPos = width + this.cSize + random(-25, 25);
    }
}

function makeCloud() {
    var cloud = {xPos: random(width), //, width*4
                speed: random(-3, -1),
                cSize: random(30, 150),
                cHeight: random(20, 60),
                yOffset: random(50, height),
                draw: cloudDraw,
                move: cloudMove};
    return cloud;
}

function drawSpring() {
// draw main cream blinds
    noStroke();
    fill(255, 251, 243);
    rect(100, ps + springHeight, 280, - height);
    var baseWidth = 20;
    push();
    rectMode(CORNERS);
// if mouse is over gray bar, turn white
    if (over || move) {
        fill(255);
    } else {
        fill(204);
    }

    rect(left, ps, right, ps + springHeight);
    pop();
}

function updateSpring() {
// update the spring position
    if (!move) {
        f = -sConstant * ( ps - rest );
        as = f / mass; // acceleration
        vs = damping * (vs + as); // velocity
        ps = ps + vs;        // updated position
    }

    if (abs(vs) < 0.1) {
        vs = 0.0;
    }

  // see if mouse is over bottom bar
    if (mouseX > left & mouseX < right && mouseY > ps && mouseY < ps + springHeight) {
        over = true;
    } else {
        over = false;
    }

// constrain position of bottom bar
    if (move) {
        ps = mouseY - springHeight/2;
        ps = constrain(ps, minHeight, maxHeight);
    }
}

function mousePressed() {
    if (over) {
        move = true;
    }
}

function mouseReleased() {
    move = false;
}

// move through 4 slides
function keyPressed() {
    option++;
    if (option > 4) option = 1;
}

My final project is based off of a book I enjoyed from childhood called Zoom, by Istvan Banyai. I tried to replicate a small glimpse of the premise of the book, which is to keep zooming out as each page is turned. My project starts off with a zoomed in sunflower and it eventually zooms out to a house. In my project, I wanted to make the zoom outs seem less static, so I incorporated movement and interactions in each scene. Some interactions include clicking for a spring effect, pressing for rain, moving the mouse around for color changes, and making sounds for objects to appear.

Instructions:
Press any key to move on to the next scene.

Scene 1 shows a zoomed in flower with floating particles.
Scene 2 zooms out to show more flowers in randomized positions. The color of sky changes depending on mouse position and it starts to rain when the mouse is pressed.
Scene 3 zooms out to a window view of the flowers. when the mouse is in the window, the sky gets darker. Also when the gray bar is clicked, the curtain gives a spring effect.
Scene 4 zooms out to outside the house. The interaction is based off of sound, so if there is a loud sound, fireflies will appear in random positions.

Eunice Choe – Project-12-Proposal

For my final project, I want to mimic the effect of a book I read in elementary school called Zoom by Istvan Banyai. The book is composed of several landscapes that zoom out as each page is turned. As a result, the zoom outs continually cause shifts in perspective and allow readers to embark on a journey through several different landscapes and environments. With each zoom out, I plan to incorporate animations within each landscape that reflect the environment. For example, I will incorporate elements of gravity and physics to make the landscapes seem more realistic. I will also make my project interactive by allowing the user to click on a “zoom out” button that will show a new, zoomed out landscape. I also plan to incorporate elements of randomness in the landscapes so that the users will have a different experience every time they interact with the project. While I am unsure of how many frames I will incorporate, I hope to create the same effect the book gives off with each zoom out.

A sketch of the “zooming out” effect.

Inspiration (pages of Zoom):

Eunice Choe – Looking Outwards-12

Rise and Fall from Design I/O on Vimeo.

The colors change over time or when the user clicks.

Base Camo by Leander Herzog

The two projects I am comparing are Basecamp (2014) by Leander Herzog and Rise and Fall (2010) by Design I/O. Basecamp by Leander Herzog is an interactive animation of colorful pyramids made with D3.js. The animation is interactive because it changes color every time the user clicks on the screen. I admire the simplistic and colorful aspects of the animation and how it responds to the user through the color changes. For my final project, I want to create interactive, animated landscapes, so this project gives me a reference of how I can show depth and layering in my composition. Because the animation is simple, it lacks a narrative, which is more prevalent in the other project Rise and Fall by Design I/O. Rise and Fall is an interactive magazine cover made with openFrameworks. By rotating the magazine, the user goes through a journey in which they interact with surreal creatures and environments that switch back and forth from water to sky. I admire that this project allows the user to control their own paths and stories. I also admire how the animations respond to gravity and physics, which adds a sense of realism and complexity.

Eunice Choe – Project-11 – Composition

sketch

/* Eunice Choe
Section E
ejchoe@andrew.cmu.edu
Project-11*/


var r;
var g;
var b;
var turtle =[];

function setup() {
    createCanvas(400, 400);
    background(255, 206, 198);
    for (var t = 0; t < 5; t ++) {
        turtle[t] = makeTurtle(width / 2, height / 2); // sets initial position
        turtle[t].penDown;
    }
}

function draw() {
    for (var t = 0; t < turtle.length; t ++) {
        r = random(100, 255);
        g = random(10, 255);
        b = random(50, 255);
        turtle[t].setColor(color(r, g, b)); // random turtle colors
        turtle[t].setWeight(random(-0.5, 5)); // random weights
        turtle[t].penDown();
        turtle[t].forward(random(10, 70)); // random lengths
        turtle[t].right(-100, 50); // random directions
        turtle[t].penUp();
  }
  frameRate(5);
}

function mousePressed()  {
    var turtle = makeTurtle(mouseX, mouseY);
    turtle.penDown();
    turtle.setColor(255);
    for (var i = 0; i < 20; i++) { // makes random white stroke shapes
        turtle.forward(random(10, 20));
        turtle.right(200);
        turtle.forward(random(10, 20));
    }
    turtlePenUp();
}

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

For my project, I wanted to create an abstract composition that shows a sense of randomness. I incorporated the randomness through randomized colors, strokes, and turtle directions. Someone interacting with this composition can also click the mouse and randomized white strokes will appear. Overall, I think the randomness makes the composition interesting.

The beginning of the composition.

The composition after some time passes and the added white strokes.

Eunice Choe – Looking Outwards-11

People can interact with sounds on the walls, floor, and ceiling.

LINES (2016) is an interactive sound art installation created by Anders Lind. I admire this project because it allows people to interact with the sounds by touching the lines on the floor, walls, and ceiling. I admire how the exhibition is immersive and how it allows anyone to create music whether they are musically inclined or not. The sound interactions were programmed through Max/MSP. There are three instruments in the piece and each of them consist of five to fifteen sensors connected to an arduino board with an output sound card. The creator’s artistic sensibilities manifest in the form through both visual and sound elements. The creator uses different colors and shapes to distinguish between different sound effects.

Eunice Choe – Looking Outwards-10

TACTUM – Tactile Augmented Reality from Madeline Gannon on Vimeo.

This video highlights the process of creating a Tactum wearable.

An example of a final product.

Tactum (2015), by Madeline Gannon, is a skin centric design tool that allows people to design 3D printed wearables on their bodies using depth sensing and projection mapping. This modeling tool allows people to design wearables naturally. Through touching, poking, rubbing, or pinching the skin, people can easily manipulate the design of the wearables and then 3D print them. I admire this project because it is interactive, efficient, and customizable. I admire how the designer found a way to use interactive technology for fashion and functional purposes. This project was led by Madeline Gannon, the head of Madlab.cc and a PhD candidate in Computational Design at Carnegie Mellon University. She runs Madlab.cc which is a research studio that specializes in creating interfaces for wearables on the body.

Eunice Choe – Project 10 – Landscape

sketch

/*Eunice Choe
Section E
ejchoe@andrew.cmu.edu
Project-10*/

var cloud = [];
var trees = [];
var terrainSpeed = 0.0001;
var terrainDetail1 = 0.005;
var terrainDetail2 = 0.008;


function setup() {
    createCanvas(480,300);
    angleMode(DEGREES);
    // initial collection of trees and clouds
    for (var i = 0; i < 10; i++) {
        var cloudX = random(width);
        var rx = random(width);
        cloud[i] = makeCloud(cloudX);
        trees[i] = makeTree(rx);
    }
}

function draw() {
    background(255, 223, 197);
    // dark mountains in background
    push();
    beginShape();
    fill(104, 101, 181);
    vertex(0,height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail2) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, 0, height);
        vertex(x, y - 50);
    }
    vertex(width, height);
    endShape();
    pop();

    // light mountains in background
    push();
    beginShape();
    fill(165, 168, 199);
    vertex(0,height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail1) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, 0, height);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
    pop();

    displayHorizon();
    updateTrees();
    removeTrees();
    randomTrees();
    fill(165, 168, 199);

    // drawing and moving the transparent clouds
    for(var i = 0; i < cloud.length; i++) {
        cloud[i].draw();
        cloud[i].move();
    }
}

function cloudDraw() {
    push();
    translate(this.xPos, this.yOffset);
    stroke(255, 255, 255, 60);
    strokeWeight(this.cHeight);
    line(0, 0, this.cSize, 0);
    pop();
}

// when moving clouds reach edge
// send them to other edge with random position, size, height
function cloudMove() {
    this.xPos += this.speed;
    if(this.xPos < 0 - this.cSize - 30) {
        this.cHeight = random(10, 50);
        this.cSize = random(30, 150);
        this.xPos = width + this.cSize + random(-25, 25);
    }
}

function makeCloud() {
    var cloud = {xPos: random(width), //, width*4
                speed: random(-0.4, -0.3),
                cSize: random(30, 150),
                cHeight: random(20, 60),
                yOffset: random(50, height),
                draw: cloudDraw,
                move: cloudMove};
    return cloud;
}

function updateTrees(){
    // Update the trees positions
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

// if trees hit edge, then remove from array
function removeTrees(){
    var keepTrees = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            keepTrees.push(trees[i]);
        }
    }
    trees = keepTrees;
}

// with probability, add tree to the end
function randomTrees() {
    var newTreeLikelihood = 0.007;
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

// update position of tree every frame
function treeMove() {
    this.x += this.speed;
}


// drawing the trees
function treeDisplay() {
    var floorHeight = 10;
    var bHeight = this.nFloors * floorHeight;
    noStroke();
    // tree trunk
    push();
    translate(this.x, height - 100);
    fill(204, 187, 145);
    rect(0, -bHeight, this.breadth, bHeight);
    // tree trunk reflections
    fill(204, 187, 145, 50);
    rect(0, -bHeight + bHeight, this.breadth, bHeight);

    // tree leaves
    fill(255, 136, 112);
    ellipse(2.5, -bHeight, 35, bHeight);
    //tree leaves reflections
    fill(255, 136, 112, 50);
    ellipse(2.5, bHeight, 35, bHeight);
    pop();
}


function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
             breadth: 5,
             speed: -1.0,
             nFloors: round(random(2,8)),
             move: treeMove,
             display: treeDisplay}
    return tr;
}

function displayHorizon(){
    noStroke();
    // water
    fill(192, 219, 212);
    rect(0,height-100, width, height-50);
    // grqss
    fill(152, 194, 146);
    rect(0,height-100, width, 20);
}

Overall, I found this project a little challenging. I had a solid plan with my sketch and I was able to execute it, but I found myself getting easily confused because there were so many lines of code. However, when I got the code figured out, I was able to capture the calmness and serenity of a mountain landscape. Along with the mountains in the background, I added trees, water, and tree reflections in the front. I also added moving transparent clouds that overlay the canvas. While this project was difficult for me, I am satisfied with the outcome and the skills I developed from it.

My initial sketches.

Eunice Choe – Looking Outwards-09

The Bund Finance Center combines traditional Chinese theatre and digital technology.

A Looking Outwards report that I found interesting and unfamiliar was the report by my peer Jacky Tian. Jacky’s first Looking Outwards report was about the Bund Finance Center in Shanghai China. This building inspired Jacky because it combines traditional Chinese elements with digital technology. Like Jacky, I am also interested in seeing environments that combine physical and digital spaces. Seeing architectural structures and pieces of art that combine physical and digital elements allow for more interaction with the people in the space. Digital technologies also allow people to have new, dynamic experiences and emotions that are not static and one dimensional. As I am continuing my education, I find that I am becoming more and more interested in discovering design and architecture that incorporate digital technology.

Eunice Choe – Project-09 – Portrait

sketch

/*Eunice Choe
Section E
ejchoe@andrew.cmu.edu
Project-09*/

var underlyingPic;

function preload(){
    var imageURL = "https://i.imgur.com/EhGYYMu.jpg";
    underlyingPic = loadImage(imageURL);
}

function setup() {
    createCanvas(320, 480);
    background(200, 100, 107);
    underlyingPic.loadPixels();
}

function draw() {
    var px = random(width);	//random y within width
    var py = random(height);	//random x within height
    var iX = constrain(floor(px), 0, width-1);
    var iY = constrain(floor(py), 0, height-1);
    //extracting color from base image
    var colorAtXY = underlyingPic.get(iX, iY);
    noStroke();
    fill(colorAtXY);
    // ellipses with random widths and heights fill canvas
    ellipse(px, py, random(1, 10), random(1, 10));

   	// when the mouse moves across canvas, rectangles of random
    // sizes will follow the mouse
    var colorAtMouse = underlyingPic.get(mouseX, mouseY);
   	fill(colorAtMouse);
    noStroke();
   	rect(mouseX, mouseY, random(3, 6), random(3, 6));
   }

function mousePressed(){
    // when mouse clicks, the name "sophia" appears on mouse location
    // with base image colors
    var colorAtXY = underlyingPic.get(mouseX, mouseY);
    textSize(20);
    text("sophia", mouseX, mouseY);


   }

My project reveals an image of my friend Sophia through ellipses of random widths and heights. Also, someone can use the mouse to speed up the image reveal because there is a trail of rectangles that follow the mouse’s location. Another fun element I added was showing Sophia’s name when the mouse is clicked on the canvas. Overall, this project was fun to complete because of its personal significance to me. Going forward, I am excited to see how I can represent more images computationally.

This screenshot shows the start of the image reveal, the trail of rectangles, and the “sophias” that appear when clicked.
The final image that appears.
The original image.

Eunice Choe – Looking Outwards-08

Zach Lieberman – Eyeo Festival 2011 from Eyeo Festival on Vimeo.

Artist Zachary Lieberman is a a creative coder who utilizes technology to create new, unexpected realities. He has held positions at several creative firms around the world and he currently teaches at the Parsons School of Design. In addition, he studied Design and Technology at Parsons. According to his website, his goal is to surprise people using technology that “breaks down the fragile boundary between the visible and invisible.” Zachary Lieberman’s body of work is centered around using technology and computational methods to create art. In his presentation, Zach Lieberman discusses IQ font, which is his project that takes the movement of a driving car and turns it into a custom typeface. Lieberman worked with two typographers and a professional race pilot to design the font and he tracked the car movements with a software that he designed. I admire this project because it directly takes inspiration from a movement and translates that movement into art. In his presentation, Lieberman articulates his thoughts clearly and he effectively combines his speaking points with visuals. These strategies kept me engaged as a viewer, so I think I could implement these strategies when I talk about my own work.


The IQ Font project was for Toyota to have a custom typeface.