// 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.
Since this doesn’t load properly on WP, access zip file here!
]]>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.
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.
]]>
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.
// 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.
]]>
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.
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
// 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.
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
// 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.
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.
]]>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.
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.
]]>