Yoo Jin Shin- Final Project

Final

// Yoo Jin Shin
// yoojins@andrew.cmu.edu
// Section D
// Final Project

// All scenes global variables
var yaxis = 1;
var xaxis = 2;
var frames = []; 
var frameCounts = 0;
var textSpeed = 3;
var slider;
var sliderValue;

// Yeosu global variables
var c1, c2, c3, c4;
var terrainSpeed1 = 0.0001; 
var terrainDetail1 = 0.003;
var terrainSpeed2 = 0.00012;
var terrainDetail2 = 0.0045;
var terrainSpeed3 = 0.00007;
var terrainDetail3 = 0.0006;
var clouds = []; 
var trees = [];
var textX = 1;
var sunMouse; 
var birdLoad;
var bird1;
var birds = [];

// Grand Canyon global variables
var terrainSpeed4 = 0.00003;
var terrainDetail4 = 0.0005;
var terrainSpeed5 = 0.00012;
var terrainDetail5 = 0.007;
var terrainSpeed6 = 0.00007;
var terrainDetail6 = 0.0065;
var textX3 = 1;
var c9;

// Las Vegas global variables
var c5, c6, c7, c8;
var buildings = [];
var snowflakes = [];
var drops = [];
var textX2 = 1;
var buildingMouse;
var carLoad;
var car1;
var cars = [];

function preload(){
    // Loading sprite sheet for girl character via direct links from imgur
    // Creds to https://www.gameart2d.com/freebies.html
    var filenames = [];
      filenames[0] = "https://i.imgur.com/oEJGbCm.png";
      filenames[1] = "https://i.imgur.com/QsZoWMJ.png";
      filenames[2] = "https://i.imgur.com/kyo4lhi.png";
      filenames[3] = "https://i.imgur.com/XmPYK4a.png";
      filenames[4] = "https://i.imgur.com/w80hQ6A.png";
      filenames[5] = "https://i.imgur.com/0BiNaBy.png";
      filenames[6] = "https://i.imgur.com/WL7kjhR.png";
      filenames[7] = "https://i.imgur.com/z6agkKq.png";
      filenames[8] = "https://i.imgur.com/Vxi5Eu6.png";
      filenames[9] = "https://i.imgur.com/mrjcctG.png";
      filenames[10] = "https://i.imgur.com/oDP8zsr.png";
      filenames[11] = "https://i.imgur.com/DsNFucK.png";
      filenames[12] = "https://i.imgur.com/8Y3e8BW.png";
      filenames[13] = "https://i.imgur.com/aQUjC1v.png";
      filenames[14] = "https://i.imgur.com/6yQMDLO.png";
      filenames[15] = "https://i.imgur.com/fJZPSul.png";
      filenames[16] = "https://i.imgur.com/vghvvNP.png";
      filenames[17] = "https://i.imgur.com/oh2WsXz.png";
      filenames[18] = "https://i.imgur.com/yPh4Upu.png";
      filenames[19] = "https://i.imgur.com/k0wd9HK.png";

    for (var i = 0; i < filenames.length; i++) {
        frames.push(loadImage(filenames[i]));
    }

    // Loading bird and car images created using illustrator
    birdLoad1 = "https://i.imgur.com/RQSUNmm.png";
    bird1 = loadImage(birdLoad1);

    carLoad1 = "https://i.imgur.com/yKCei98.png";
    car1 = loadImage(carLoad1);
}

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

  // Yeosu: Define gradient colors
  c1 = color(225, 217, 199); // sky top color - grey
  c2 = color(254, 180, 144); // sky bottom color - orange
  c3 = color(50, 50, 2); // ground left - lighter green
  c4 = color(27, 20, 2); // ground right - dark green

  // Yeosu: Initialize clouds
  for (var i = 0; i < 3; i++) {
      var cloudX = random(width); 
      clouds[i] = drawClouds(cloudX);
  }

  // Yeosu: Initialize trees
  for (var i = 0; i < 7; i++) {
    var treeX = random(width);
    var t = drawTrees(treeX);
    trees[i] = t;
  }

  // Yeosu: Initialize birds
  for (var i = 0; i < 7; i++) {
    var birdX = random(width);
    birds[i] = drawBird(birdX);
  }

  // Las Vegas: Define gradient colors
  c5 = color(0, 0, 0); // sky top color - black
  c6 = color(61, 48, 52); // sky bottom color - purpley

  // Las Vegas: Initialize buildings
  for (var i = 0; i < 6; i++) {
      var rx = random(width);
      buildings[i] = drawBuilding(rx);
  }  

  // Las Vegas: Initialize cars
  for (var i = 0; i < 10; i++) {
    var carX = random(width);
    cars[i] = drawCar(carX);
  }
    imageMode(CENTER);
}

function drawSlider() {
  slider = createSlider(5, 60, 30);
  slider.style(200, '100px');
  slider.position(20, 450);
}

function draw() {
  // Set slider to adjust frameRate
  var frameRateSpeed = slider.value();
  frameRate(frameRateSpeed);
  
  // Change scene every 160 frames, then loop
  // Loop: Yeosu - GrandCanyon1 - LasVegas - GrandCanyon2
  if (frameCounts <= 160) { // 160
      drawYeosu();
  }
  else if (frameCounts >= 160 & frameCounts < 320) {
      drawGrandCanyon(); // transition: light to dark sky
  } 
  else if (frameCounts >= 320 & frameCounts < 480) {
    drawLasVegas();
  }
  else if (frameCounts >= 480 & frameCounts < 640) {
    drawGrandCanyon2(); // transition: dark to light sky
  }
  else if (frameCounts === 640) {
    frameCounts = 0;
  }  
  frameCounts++;
}

// =====================================================================
// ==============================YEOSU==================================
// =====================================================================

function drawYeosu() {
  setGradient(0, 0, width, height / 2 + 70, c1, c2, yaxis); // sky
  drawSun();
  drawMountain1();
  drawMountain2();
  drawOcean();
  drawSunReflection();
  updateClouds();
  removeClouds();
  addClouds();
  setGradient(0, 390, width, 480, c3, c4, xaxis); // ground
  updateTrees();
  removeTrees();
  addTrees();
  drawMe();
  drawFog();
  updateBird();
  removeBird();
  addBird();
  writeText();
}

function setGradient(x, y, w, h, c1, c2, axis) {
  // Top to bottom gradient
  if (axis == yaxis) { 
    for (var i = y; i <= y + h; i++) {
      var inter = map(i, y, y + h, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(x, i, x + w, i);
    }
  }
  // Left to right gradient
  else if (axis == xaxis) {
    for (var i = x; i <= x + w; i++) {
      var inter = map(i, x, x + w, 0, 1);
      var c = lerpColor(c1, c2, inter);
      stroke(c);
      line(i, y, i, y + h);
    }
  }
}

function drawMountain1(){
  noStroke();
  fill(204, 157, 135); 
  beginShape(); 
  for (var x = 0; x < width; x++) {
    var t = (x * terrainDetail1) + (millis() * terrainSpeed1);
    var y = map(noise(t), 0, 1.8, height / 4 - 10, height);
    vertex(x, y); 
  }
  vertex(width, height);
  vertex(0, height);
  endShape();
}

function drawFog() { 
  for (var y = 200; y < height + 5; y++) {
    var f = map(y, height / 2 - 40, 550, 0, 100);
    stroke(255, f);
    line(0, y, width, y);
  }
}

function drawMountain2(){
  fill(147, 126, 115); 
    noStroke();
    beginShape(); 
      for (var x = 0; x < width; x++) {
            var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
            var y = map(noise(t), 0, 2, height / 4 + 60, height);
            vertex(x, y); 
      }
      vertex(width,height);
      vertex(0,height);
    endShape();
}

function drawOcean() {
    fill(170, 146, 121); 
    noStroke();
    beginShape(); 
      for (var x = 0; x < width; x++) {
            var t = (x * terrainDetail3) + (millis() * terrainSpeed3);
            var y = map(noise(t), 0, 2, height - 230, height);
            vertex(x, y); 
      }
      vertex(width, height);
      vertex(0, height);
    endShape();
}

function drawSun() {
	// All sun parts based on mouseY
  	sunMouse = constrain(mouseY, 0, height / 3 + 30);
    noStroke();
    // Sunglow
    // Color less intense and size smaller as sun goes farther up
    fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.02);
    ellipse(width / 3, sunMouse + 40, sunMouse - 10, sunMouse - 10);
    fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.03);
    ellipse(width / 3, sunMouse + 40, sunMouse*1.1, sunMouse*1.1);
    fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.05);
    ellipse(width / 3, sunMouse + 40, sunMouse*1.2 + 10, sunMouse*1.2 + 10);
    // Sunrays
    fill(253, 254, 221, 30);
    triangle(width / 3, sunMouse + 20, width / 3 - 40, height / 3 + 90, width / 3 - 10, height /3 + 80); // left big
    triangle(width / 3, sunMouse + 20, width / 3 + 40, height / 3 + 80, width / 3 + 10, height /3 + 70); // right big
    triangle(width / 3, sunMouse + 20, width / 3 - 50, height / 3 + 90, width / 3 - 30, height /3 + 80); // left small
    triangle(width / 3, sunMouse + 20, width / 3 + 50, height / 3 + 80, width / 3 + 30, height /3 + 70); // right small
    triangle(width / 3, sunMouse + 20, width / 3 - 70, height / 3 + 70, width / 3 - 80, height /3 + 70); // left small2
    triangle(width / 3, sunMouse + 20, width / 3 + 70, height / 3 + 90, width / 3 + 80, height /3 + 80); // right small2
    // Sun
    fill(253, 254, 221, sunMouse + 30);
    ellipse(width / 3, sunMouse + 40, sunMouse - 20, sunMouse - 20);
}

function drawSunReflection() { 
	// Size of reflection on ocean corresponds to sun size/distance away
    var x = 10;
    var y = 47;
    var w = sunMouse;
    var h = 10;
    noStroke();
    // Outer darker glow
    fill(248, 172, 137, 100);
    push();
    rectMode(CENTER);
    rect(width / 3, 2 * height / 3 + y, w, h, 10);
    rect(width / 3, 2 * height / 3 + y - 13, w * 0.8, h, 10);
    rect(width / 3, 2 * height / 3 + y - 26, w * 0.6, h, 10);
    // Inner lighter glow
    fill(253, 254, 221, 50);
    rect(width / 3, 2 * height / 3 + y - 4, w * 0.9, h * 0.8, 10);
    rect(width / 3, 2 * height / 3 + y - 17, w * 0.7, h * 0.8, 10);
    rect(width / 3, 2 * height / 3 + y - 30, w * 0.5, h * 0.8, 10);
    pop();
}

function updateClouds(){
  for (var i = 0; i < clouds.length; i++) {
    clouds[i].move();
    clouds[i].display();
  }
}

function removeClouds(){
  var keepClouds = [];
  for (var i = 0; i < clouds.length; i++) {
      if (clouds[i].x - this.width / 2 < width) {
        keepClouds.push(clouds[i]);
      }
  }
  clouds = keepClouds;
}

function addClouds(){
  var newCloud = 0.01;
  if (random(0, 1) < newCloud) {
    clouds.push(drawClouds(random(width)))
  }
}

function moveClouds(){
  this.x += this.speed;
}

function displayClouds(){
  var b = random(165, 180);
  fill(255, 240, 240, 30);
  ellipse(this.x, this.y, this.width, this.height);
  ellipse(this.x + 50, this.y + 10, this.width - 20, this.height - 70);
  ellipse(this.x - 50, this.y - 5, this.width - 70, this.height - 10);
}

function drawClouds(newCloudX) {
  var cloud = {
    x: newCloudX,
    y: random(30, height / 2),
    width: random(150, 250), 
    height: random(20, 50),
    speed: random(0.5, 1.5),
    move: moveClouds,
    display: displayClouds
  }
  return cloud;          
}

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

function removeTrees() {
  var keepTrees = [];
  for (var i = 0; i < trees.length; i++) {
    if (trees[i].x < width) {
      keepTrees.push(trees[i]);
    }
  }
  trees = keepTrees;
}

function addTrees() {
  var newTree = 0.02;
  if (random(0, 1) < newTree) {
    trees.push(drawTrees(random(width)));
  }
}

function moveTrees() {
  this.x += this.speed;
}

function displayTrees() {
  // Tree height based on mouseY, mapped to a reasonable extent
  var treeMouse = map(mouseY, 0, height, height / 3, 0);
  var treeMouseCon = constrain(treeMouse, 0, height)
  // Trunk
  stroke(c4);
  strokeWeight(4);
  line(this.x, this.y + 20 - treeMouseCon, this.x, this.y + 40);
  // Leaves
  fill(c3, 20);
  stroke(c3);
  strokeWeight(7);
  strokeJoin(ROUND);
  triangle(this.x, this.y - treeMouseCon, this.x + 20, this.y + 25, this.x - 20, this.y + 25);
  // Add snow if on Grand Canyon scene
  if (frameCounts >= 160 & frameCounts < 320 || frameCounts >= 480 && frameCounts < 640) {
    fill(250);

This project was inspired by my love of taking photos, especially of nature and cityscapes. I tried recreating the feel and weather of three shots below in a looping generative landscape. Follow me! You can speed up or slow my pace using the slider and control objects like the sun and buildings using the mouse.

Scene 1 – Sunrise at Yeosu (Javascript, my photo, sketch)
Scene 2 – Snowy Grand Canyon
Scene 3 – Rainy Las Vegas

Since this doesn’t load properly on WP, access zip file here!

Yoo Jin Shin-LookingOutwards-12

Interactive Resume (2018) by Robby Leonardi

The first project is an interactive resume by Robby Leonardi. It’s colorful, fun, and highly interactive. The user scrolls up or down to move the figure through Robby’s resume. It really shows off the designer’s personality. One thing is that there is no link to a portfolio of his actual works/projects.

Interactive Resume (2018) by Charles Richard

The second project is another online resume by Charles Richard. Similarly, the user scrolls up or down to navigate through Charles’s resume. However, this project uses more muted colors. One thing I noticed is that he uses circles throughout his project so it’s difficult to tell at a glance which ones are buttons and which ones are simply for aesthetics. Overall, I think both of these projects are fun, interactive ways to display one’s resume.

 

Yoo Jin Shin-Project-12-Proposal

For the final project, I would like to create some sort of interactive display or animation for the home page of my personal website. I saw one in which the home screen included an interactive color wheel in which each color block led to a different project once clicked. Another included an animation that told a short story of the portfolio owner’s background/works. For the first idea, a lot would depend on the mouse positions and including images while the second idea would be some sort of generative landscape with mostly nonrandom elements.

Sketches

Yoo Jin Shin-Project-11-Composition

Project-11

// Yoo Jin Shin
// Section D
// yoojins@andrew.cmu.edu
// Project 11 Turtle Freesytle

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

var particles = [];

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

    // Making particles/"rain"
    for (var i = 0; i < np; i++) {
        var p = makeParticle(200, 200,
                             random(-50, 50), random(-50, 50));
        particles.push(p);
    }
    frameRate(10);
}

function draw() { 
    // Gradient green/grass background based on mouse
    var r = map(mouseX, 0, width, 70, 120); 
    var b = map(mouseY, 0, height, 90, 120);
    background(r, 170, b);

    // Center rose on mouse
    var ttl = makeTurtle(mouseX, mouseY);
    ttl.penDown();
    ttl.setColor("pink");
    ttl.setWeight(1);
    ttl.left(frameCount);
    ttl.face(190);

    for (var i = 0; i < 25; i++) {
        ttl.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl.forward(3 + i * 2);
            ttl.left(80);
        }
    }
    ttl.penUp();

    /// Left smaller rose 
    var ttl2 = makeTurtle(mouseX - 50, mouseY);
    ttl2.penDown();
    ttl2.setColor(150);
    ttl2.setWeight(1);
    ttl2.left(frameCount);
    ttl2.face(190);

    for (var i = 0; i < 10; i++) {
        ttl2.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl2.forward(2 + i * 2);
            ttl2.left(70);
        }
    }
    ttl.penUp();

    /// Right smaller rose 
    var ttl2 = makeTurtle(mouseX + 50, mouseY);
    ttl2.penDown();
    ttl2.setColor(150);
    ttl2.setWeight(1);
    ttl2.left(frameCount);
    ttl2.face(190);

    for (var i = 0; i < 10; i++) {
        ttl2.face(225 - i * 100);
        for (var j = 0; j < 6; j++) {
            ttl2.forward(2 + i * 2);
            ttl2.left(70);
        }
    }
    ttl.penUp();

    // Draw all particles in the array
    if (mouseIsPressed) {
        var newp = makeParticle(mouseX, mouseY,
                                random(-10, 10), random(-10, 0));
        particles.push(newp);
    }

    newParticles = [];
    for (var i = 0; i < particles.length; i++) { 
        var p = particles[i];
        p.step();
        p.draw();
        if (p.age < 200) {
            newParticles.push(p);
        }
    }
    particles = newParticles;

}

var gravity = 0.3; // downward acceleration
var springy = 0.7; // how much velocity is retained after bounce
var drag = 0.0001; // drag causes particles to slow down
var np = 100;      // how many particles
var COLORS = ["White", "#86E3F2", "#37A3B5", "#357CA8", "#14608E"];

function particleStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx * springy;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx * springy;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy * springy;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy * springy;
    }
    this.dy = this.dy + gravity; // force of gravity
    var vs = Math.pow(this.dx, 2) + Math.pow(this.dy, 2);
    var d = vs * drag;
    d = min(d, 1);

    // Repelling force from center rose
    var rpx = mouseX;
    var rpy = mouseY;
    var d2 = dist(rpx, rpy, this.x, this.y);
    var rpc = 9000;
    var f = rpc / (Math.pow(d2, 2));
    var dirx = (this.x - rpx) / d2;
    var diry = (this.y - rpy) / d2;
    // scale dx and dy to include drag effect
    this.dx *= (1 - d);
    this.dx += dirx * f;
    this.dy *= (1 - d)
    this.dy +=  diry * f;
}

function particleDraw() {
  fill(this.particleColor);
  noStroke();
  ellipse(this.x, this.y, this.particleSize, this.particleSize);
  point(this.x, this.y);
}

function pickColor() {
  return COLORS[int(random(COLORS.length))];
}

function pickSize() {
  return random(5, 30);
}

// create a "Particle" object with position and velocity
function makeParticle(px, py, pdx, pdy) {
    p = {x: px,
       y: py,
         dx: pdx, 
         dy: pdy,
         age: 0,
         step: particleStep,
         draw: particleDraw,
         particleColor : pickColor(),
         particleSize : pickSize(),
        }
    return p;
}

I created this project with a flower garden in mind: there are rose-like shapes created using turtle, a green, grass-like background, and many blue, rain-like particles. There is a force around the center rose that repels the rain.

Repelling force

 

Yoo Jin Shin-LookingOutwards-11

Sonic Playground

Sonic Playground (2018) at the High Museum of Art, Atlanta, GA

Sonic Playground by Yuri Suzuki is “an outdoor sound installation that features ingenious, colourful sculptures that modify and transmit sound in unusual, engaging and playful ways.” The colors used in the installation are so vibrant and really catch the eyes of those passing by.

Rhinoceros 3D / Grasshopper Pipes

The software behind this installation was designed by Luca Dellatorre using Grasshopper, as a parametric design plug-in in Rhinoceros. “The plug in he wrote is a 3D raytracing tool that allows the user to select a sound source and send sound in a certain direction or towards a certain geometry, in this case the shape of the acoustic mirrors or the bells at the start and end of the pipes to see how the sound is reflected and what is the interaction with the object.” It’s cool to see how such a seemingly simple installation can have such a complex architecture on the back-end.

Yoo Jin Shin-Project-10-Generative Landscape

Project-10

// Yoo Jin Shin
// Section D
// yoojins@andrew.cmu.edu
// Project 10: Generative Landscape

var buildings = [];
var terrainSpeed = 0.0003;
var terrainSpeed2 = 0.0002;
var terrainSpeed3 = 0.0001;
var terrainDetail = 0.003;
var terrainDetail2 = 0.005;
var terrainDetail3 = 0.006;

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

    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    frameRate(10);
}
 
function draw() {
    background(255);
    terrain3();
    terrain2();
    terrain();
    building();
}

// blue terrain in front
function terrain() {
    push();
    var R = random(5, 40);
    var G = random(5, 40);
    fill(R, G, 80);
    stroke(255);
    strokeWeight(6);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, 0, height);
        vertex(x, y); 
    }
    endShape();
    pop();
}

// purple terrain in middle
function terrain2() {
    push();
    var R = random(40, 60);
    var G = random(0, 30);
    fill(R, G, 80);
    stroke(255);
    strokeWeight(3);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
        var y = map(noise(t), 0, 2, 0, height);
        vertex(x, y); 
    }
    endShape();
    pop();
}

// pink terrain in back
function terrain3() {
    push();
    var G = random(0, 40);
    var B = random(90, 100);
    fill(120, G, B);
    stroke(255);
    strokeWeight(1);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail3) + (millis() * terrainSpeed3);
        var y = map(noise(t), 0, 3, 0, height);
        vertex(x, y); 
    }
    endShape();
    pop();
}
    
function building() { 
    push();
    translate(0.1 * width, 0.1 * height); 
    scale(0.8);
    displayHorizon();
    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 
    pop();
}


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

function removeBuildingsThatHaveSlippedOutOfView(){
    var buildingsToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingsToKeep.push(buildings[i]);
        }
    }
    buildings = buildingsToKeep; 
}

function addNewBuildingsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newBuildingLikelihood = 0.007; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

function buildingMove() {
    this.x += this.speed;
}
    
// draw alien buildings with changing colors 
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    var B = random(100, 255);
    var R = random(100, 255);
    fill(R, 255, B); 
    stroke(0); 
    strokeWeight(2);

    push();
    translate(this.x, height - 40);
    ellipse(0, -bHeight + 20, this.breadth, bHeight * 2);

    // draw windows
    stroke(0); 
    strokeWeight(2);
    fill(0);
    for (var i = 0; i < this.nFloors; i++) {
        rect(-5, -15 - (i * floorHeight + 10), 10, 10);
    }
    pop();
}

function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: round(random(30, 80)),
                speed: -2,
                nFloors: round(random(3, 7)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function displayHorizon(){
    noStroke();
    fill(0, 43, 7);
    rect(-200, height - 150, width + 300, height - 150); 
}

I tried creating an alien world generative landscape. The sky portion of the landscape has three terrains varying in color and speed, looking somewhat like clouds. The buildings vary in size and color, looking almost like cacti. This project was rather challenging, but I would definitely experiment more with generative landscapes in the near future and try creating more elaborate ones.

Sketch

Yoo Jin Shin-LookingOutwards-10

Shin’m 2.0

Shin’m 2.0 (2011)

Shin’m 2.0 (2011) is an interactive installation and performance by media artist Eunsu Kang, in collaboration with software engineer Donald Craig and dancer and choreographer, Diana Garcia-Snyder. The project portrays “how we communicate with the space, how we connect into it, and how we and the space reshape each other.” The space is filled with nebula bubbles constantly circulating through a black hole in the center. Both light and sound follow the participant’s movements using the GLUT application with C++ along with kinetic sensors.

The still image of the Shin’m 2.0 was enough to catch my attention. It’s simply stunning and looks like something out of a movie. This effect is emphasized in the video of the installation— it seriously looks like CG. I think it’s admirable that Kang started the Shin’m project back in 2008 and has repeatedly made adjustments and improved on her design to get to this point.

Kang received her BFA and MFA at Ewha Womans University in South Korea, MA in Media Arts and Technology from UC Santa Barbara, and a PHD in Digital Arts and Experimental Media from University of Washington. She currently works as a associate professor of art at University of Akron and regularly holds exhibitions of her various media designs.

Yoo Jin Shin-Project-09-Portrait

Project-09

// Yoo Jin Shin
// Section D
// yoojins@andrew.cmu.edu
// Project-09-Portrait

var underlyingImage;

function preload() {
    var myImageURL = "https://i.imgur.com/P9QQAmA.png";
    underlyingImage = loadImage(myImageURL);
}

function setup() {
    createCanvas(480, 416);
    background(255);
    underlyingImage.loadPixels();
    frameRate(500);
}

function draw() {
    var px = random(width);
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    var theColorAtLocationXY = underlyingImage.get(ix, iy);

    // drawing rectangles
    noStroke();
    fill(theColorAtLocationXY, random(0, 255));
    rect(px, py, random(5, 20), random(5, 20));

    // writing Bells
    noStroke();
    fill(theColorAtLocationXY);
    textFont('Helvetica');
    textSize(5);
    text("BELLS", px, py);
}

// resets with blank canvas once mouse pressed
function mousePressed() {
    clear();
}

For this project, I used a photo of my friend, Bella. I think this was especially fun and meaningful because it felt as if the final product had a specific recipient. I initially had larger end bounds for the dimensions of the rectangles, but realized that if the rectangles are too big, the end stage seems a bit too abstract to the point that you can hardly recognize the person.

 

Original photo
Early stage
Near the final stage

Yoo Jin Shin-LookingOutwards-09

Prismverse

I came across Yingyang’s post and was introduced to Chris Cheung’s Prismverse (2017) exhibition. The thumbnail of the video was enough to capture my attention—it looks like a scene from some sci-fi, futuristic movie with the chrome geometric patterns on the black floor. I love how the colors transition and how the light and water effects actually make it seem like you’re inside a diamond. It was so unexpected that this project is part of Dr.Jart+, which I was already familiar with as a skincare brand. After looking up the product that this was designed for, I thought it would have been nice if at least some part of the packaging reflected this eye-catching exhibition.

Yoo Jin Shin-LookingOutwards-08

Meejin Yoon

Meejin Yoon is a current professor and department head of architecture at MIT. She received her bachelor of architecture at Cornell and master of architecture in urban design at Harvard. She is also the co-founder of two studios in Boston. A lot of Yoon’s work focuses on interactive public space projects “that bridge issues of technology and play in the public sphere.” Yoon seems to smoothly and effectively blend the appropriate technology and architecture that align with the specific purpose and context of each project. The visuals that she uses in her presentation are mostly full-sized images, animations of the designs, and videos of her works in action. The transitions are smooth and she gives off an overall humble impression.

Collier Memorial, MIT

Out of all her projects, I really admire her “Collier Memorial” in memory of Sean Collier, an officer who was shot in the MIT campus immediately following the Boston Marathon bombings. Yoon initially had a lot of reservation because she was not used to dealing with metaphors and meaning in contemporary architecture. However, she successfully synthesized the ideas that were submitted from the open call, took the essence of these ideas, and produced a meaningful, beautiful memorial through a long, iterative process.