Vicky Zhou – Final Project

sketch

/*Vicky Zhou
vzhou@andrew.cmu.edu
Project 12 - Final
Section E*/

var particles; //number of particles in sphere system
var spacing; //spacing of particles
var waveRipple; //manipulates ripple in sphere system
var points; //array for compiling all sphere points
var speed; // speed variable for ripple sphere wave effect
var amplitude; //amplitude of wave

//variables for new toruses
var myx = [];
var myy = [];
var myz = [];

//variables for existing, old toruses
var total = 5;
var locations = new Array(total);
var bool = new Array(total);
var oldpart = [];
var oldpartsize = 12;

//to change displays
var changescene = true;


function setup() {
    createCanvas(600, 600, WEBGL);
    particles = 2000; 
    spacing = 200;
    points = [];
    speed = 0.01;
    amplitude = 0.8;
    wavecol = 0;
    
    if (changescene) {
    	//array of random points for wave of spheres
    	for (var i = 0; i < particles; i++) {
    		points[i] = createVector(random(-5, 5),
    								 random(-5, 5),
    								 random(-5, 5));
    	}
    } else {
    	//array for generated toruses
    	for (var i = 0; i < myx.length; i++) {
    		myx[i];
    		myy[i];
    		myz[i];
    	}

    	//array for already existing toruses
    	for (var i = 0; i < locations.length; i++) {
    		locations[i] = new Array(total);
    		bool[i] = new Array(total);
    		for (var j = 0; j < locations[i].length; j++) {
    			locations[i][j] = new Array(total);
    			bool[i][j] = new Array(total);
    			for (var k = 0; k < locations[i][j].length; k++) {
    				locations[i][j][k] = createVector(i * oldpartsize,
    												j * oldpartsize,
    												k * oldpartsize);
    				bool[i][j][k] = false;
    			}
    		}
    	}

    	var thres = 2; //threshold for state of Torus 
    	for (var i = 0; i < total; i++) {
    		for (var j = 0; j < total; j++) {
    			for (var k = 0; k < total; k++) {
    				stateofTorus = random(15); //random number for state 
    				if (stateofTorus <= thres) {
    					st = 1;
    					bool[i][j][k] = true;
    				} else {
    					st = 0;
    				}
    				oldpart.push(new myTorus(i * oldpartsize,
    										j * oldpartsize,
    										k * oldpartsize,
    										st));
    			}
    		}
    	}
    }
}


//create and push new coordinates for toruses when any key is pressed
function keyPressed() {
	myx.push(random(-10, 10));
	myy.push(random(-300, 300));
	myz.push(random(-300, 300));
}


function draw() {
	background(30, 30, 50);
	wavecol += 1;
	//light that is emiited
	directionalLight(wavecol/2, 200, 200, 50);
	ambientLight(80, wavecol/5, 170);
	//manipulates wave of spheres
	waveRipple = mouseX * speed;

	//center rotating cube
	push();
	rotateX(frameCount/100);
	rotateY(frameCount/100);
	noStroke();
	box(150);
	pop();

	if (changescene) {
		//array of random points to plot each sphere
		for (var i = 0; i < particles; i++) {
			var dot = points[i];
			doty = sin(dot.x + waveRipple) * amplitude;
			push();
			translate(dot.x * spacing, doty * spacing, dot.z * spacing);
			noStroke();
			sphere(10);
			pop();
		}
	} else {
		//array of existing toruses
		push();
		for (var i = 0; i < oldpart.length; i++) {
			oldpart[i].display();
		}
		pop();

		//create new toruses
		for (var i = 0; i < myx.length; i++) {
			rotateY(frameCount/500);
			push();
			if (keyIsPressed === true) {
				updatez = myz[i];
			} else {
				updatez = 100;
			}
			thenewy = cos(waveRipple) * amplitude + myy[i];
			thenewz = 0;
			directionalLight(wavecol/2, 200, 200, 50);
			translate(myx[i], thenewy, thenewz + updatez);
			var gradred = map(mouseX, 0, width, 0, 255);
			var gradgreen = map(mouseX, 0, width, 0, 200);
			fill(gradred, gradgreen, 200);
			strokeWeight(0.2);
			stroke("blue");
			torus(12, 5);
			pop();
		}
	}
}

//function to create existing toruses
function myTorus(x, y, z, st) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.st = st;

	this.display = function() {
		if (this.st == 1) {
			rotateY(frameCount/350);
			push();
			directionalLight(wavecol/2, 200, 200, 250);
			translate(this.x, this.y, this.z * 3.5);
			strokeWeight(0.2);
			stroke("blue");
			torus(oldpartsize, 5);
			pop();
		}
	}
}

//click mouse to toggle between scenes
function mousePressed() {
	changescene =! (changescene);
	setup();
}

Instructions

Mouse Click: toggle between screens

Mouse move: manipulate wave; manipulate color of toruses

Press any key: add a new torus

Hold down any key: explode toruses

Statement

“Re:current” is a project utilizing 3D graphics from WEBGL in order to manipulate arrays and variables to create interactive cyclical experiences — 1. a “current” like nature of manipulating a wave of spheres using curves to mimic ocean-like wave that changes color over time and 2. a looping interaction of adding toruses which rotate around a 3. perennially rotating cube. My greatest struggle was working and adapting to the 3D landscape and nuances of WEBGL, and being able to translate the 2D elements we learned thus far onto my canvas. For my beginning prototypes, the biggest challenge I faced with creating an interactive project was being able to manipulate factors utilizing the mouse press and mouse pressed feature, because of how a mouse inherently creates an output of 2D, whereas my project would call for 3D. I resolved this issue to the best of my ability in this short term by opting to toggle between screens and making basic interactions using the mouse, and then for more detailed engagement I utilized the key pressed feature to generate random x, y, and z coordinates. For further exploration, I would love to explore with more dynamic ways of altering the canvas, ideally in ways to can imitate biomimicry, seeing that WEBGL is able to produce interestingly rendered outcomes with its different textures, lighting, and other attributes.

Screenshots
Some screenshots of my work!

wave manipulation (color change over time)
wave manipulation
initial torus scene
adding more toruses!

Vicky Zhou – Looking Outwards 12

In my research for generative and computational artists, I came across a visual artist/programmer/designer that I really admire — Marcin Ignac. A lot of his projects deal with data visualization and generative art in visually engaging ways, many times involving the manipulation of interesting 3D spaces in aesthetic qualities. In particular, I find “Continuous Transition”, “Instancae”, and “Noise Particles”, projects the most visually stimulating, with “Instancae” being the most visually engaging. “Instancae” is a branch of a bigger project “Flora”, and it is interesting because it is a generative plant project that involves several different “plant” forms to generate output, and focuses on translating natural elements (biomimicry) onto a computational platform. I also really admire his “Continuous Translation” project because it dives into an interesting break down of undulation, that I would want to further explore in my final project. Although several of his projects do allow for interaction, “Continuous Translation” is more so an already finalized project; I would want to explore more so how the user can input data in order to manipulate the wave.

Instancae
Continuous Transition

Vicky Zhou – Project 12 – Proposal

For my final project, I would like to explore more in depth interactions developed around the concepts of gravity, springs, undulation through particle systems. To do this, I believe I will go about creating these interactive experiences through objects, or possibly turtles, depending on how I want to construct the interaction through a particle system, or a more self constructed system. Ideally, I want to create a flat plane of sort that undulates at a given frequency and amplitude, which can then be manipulated through a user’s mouse input and/or keyboard input. The most desirable outcome would be to have the plane react to mouse interaction, however, depending on how fluid the plane is, I predict that it might be not interactive and/or can only be manipulated through three forms, which will be then created through a series of clicking 3 or so keys.

I am currently between two layout ideas: having my flat plane be of a face on view, or placing it it some sort of perspective.

Vicky Zhou – Project 11 – Computation

sketch

/*Vicky Zhou
vzhou@andrew.cmu.edu
Section E
Project 11 - Freestyle with Turtles*/

//turtle array
var ttl = [];

function setup() {
	createCanvas(480, 480);
	background(180, 200, 250);
	//initializing the turtle array
	for (var i = 0; i < 5; i ++){
		t = makeTurtle(0, 0);
		ttl.push(t);
	}
}


function draw() {
	for (var i = 0; i < 5; i ++){
		fill(190, 210, 210, 200);
		stroke("blue");
		//drawing the triangle
		triangle(ttl[i].x, ttl[i].y,
			ttl[i].x + 10, ttl[i].y + 60,
			ttl[i].x + 100, ttl[i].y + 100);
		//moving the triangle
		moveTurtle();
	}

}

//function to move the triangles 
function moveTurtle() {
	for (var i = 0; i < 5; i ++){
		dx = abs(ttl[i].x - mouseX);
		if (ttl[i].x < mouseX) {
			ttl[i].x += dx / 50;
		}
		else {
			ttl[i].x -= dx / 20;
		}
		dy = abs(ttl[i].y - mouseY);
		if (ttl[i].y < mouseY) {
			ttl[i].y += dy / 100 + i;
		}
		else {
			ttl[i].y -= dy / 100 + i;
		}
	}
}



//---------------------------------------------------------------------------
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 this week’s project, because the prompt was so vague I was not entirely sure what I wanted my end product to be. However, I did want my computational turtles to be interactive with the mouse, so I centered the project around a turtle that would follow your mouse tracking and leave behind a trace. I played around with ellipses, rectangles, but then settled on a triangle because of how neatly some edges could settle in each other.

Screenshots of images you can create

Vicky Zhou – Looking Outwards 11

4G Network into Musical Sounds

For this week’s looking outward centered on computational music, I decided to focus on a project by Andrius Sarapovas: a kinetic generative music installation. This installation turns a 4G network into a series of musical sounds, based on n algorithm and through 77 segments distributed through the physical exhibition space. Each segment consists of a metal bar, a sound activator, a sound damper, a resonator, and mechatronics, that pick up on the signals in the 4G network. The placement of these segments were optimized and based on the actual physical exhibition space.

I appreciate this project because it intakes very impersonal data that we commonly and frequently discard, and/or don’t understand, and transforms it into a medium that we are more familiar with, and can enjoy.

Vicky Zhou – Looking Outwards – 10

Swing Time (2014) by Howeler + Yoon Studio

Swing Times is an interactive public installation of 20 illuminated ring-shaped swings located in Boston. At rest, the swings emit a soft, white light that lightens the area, but, once in motion, a custom micro-controller flips the LED lighting within the swing from a white to a more vibrant purple. This controller signals and measures the swing’s activity level, which then triggers the light at varying intensities. I admire this project a lot because of how it creates an engaging experience and transforms a static place into an active park for Boston residents and visitors, as I had the pleasure of personally interacting with this installation when I visited my brother in Boston.

J. Meejin Yoon is an architect, designer, educator, and co-founder of design-drive architecture studio Howeler + Yoon. She is a current professor and Head of the Department of Architecture at the Massachusetts Institute of Technology, and previously studied at Cornell University for her Bachelor of Architecture degree and Harvard University for her Master of Architecture degree in Urban Design. She also received a Fullbright Fellowship to Korea. Broadly speaking, her work revolves around innovative and interactive landscape, and subversive structural work in various communities and for various audiences. Although she is not listed as a direct member of the design team for the Swing Time project, she is in charge and principle of many other projects under her studio, such as an upcoming “Float Lab” architectural installation.

Vicky Zhou – Project 10 – Landscape

sketch

/*Vicky Zhou
Section E
vzhou@andrew.cmu.edu
Project-10-Landscape
*/

//window roll down variables 
var mtnspeed1 = 0.00009;
var mtndetail1 = 0.0002;
//mountain variables
var mtnspeed2 = 0.0001;
var mtndetail2 = 0.002;
var mtnspeed3 = 0.0008;
var mtndetail3 = 0.005;

var trees = [];
var windowrolldown = [];

function setup() {
    createCanvas(480, 480); 
    //places trees throughout landscape
    for (var i = 0; i < 10; i++){
    	var rx = random(width);
    	trees[i] = maketrees(rx);
    }
    frameRate(50);
}


function draw() {
    background(255, 220, 200); 

    makewindowrolldown();
    makemtns();

    push();
    noStroke();
    updateAndDisplaytrees();
    removetrees();
    addtrees();
    pop();

    displayCarWindow();
    displayCarMirror();
}


//creating function to show and update trees
function updateAndDisplaytrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

//removing old trees from landscape
function removetrees(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].peaks > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}

//adding new random trees 
function addtrees(){
	var newtrees = 0.005;
	if (random(0,1) < newtrees) {
		trees.push(maketrees(width));
	}
}

//moving trees across screen 
function treeMove() {
	this.x += this.speed;
}

//drawing trees 
function treeDisplay() {
    // var treeheight = 10;
    var randomtreeheight = this.tbranches;
	fill(65, 90, 85);
	push();
	translate(this.x, height - 30); // WHAT IS PURPOSE OF THIS TRANSLATE????
    triangle(this.peaks + 10, -this.peaks - 20, 
            this.peaks + 90, -this.peaks - 20,
            this.peaks + 45, -this.peaks - 210 * randomtreeheight);
	pop();
}

//making trees 
function maketrees(mx){
    // noStroke();
	var trees = {x: mx,
            tbranches: random(0.4, 1.2),
			peaks: 50,
			speed: -5.0,
			move: treeMove,
			display: treeDisplay}
	return trees;
}

//making window roll down
function makewindowrolldown() {
    push();
    beginShape();
    strokeWeight(0.2);
    stroke(60, 60, 170, 300);
    for (var x = 0; x < width; x++) {
        var t = (x * mtndetail1) + (millis() * mtnspeed1);
        var y = map(noise(t), 0, 1, height, 100);
        // vertex(x, y);
        line(x, y - 100, x, height - 100);
    }
    endShape();
    pop();
}

//making mountains 
function makemtns() {
    push();
    //light purple mountains 
    beginShape();
    stroke(150, 125, 130, 100);
    for (var x = 0; x < width; x++) {
        var t = (x * mtndetail2) + (millis() * mtnspeed2);
        var y = map(noise(t), 0, 1, 0, height);
        // vertex(x, y);
        line(x, y, x, height);
    }
    endShape();

    //dark green mountains 
    beginShape();
    stroke(60, 80, 90, 120);
    for (var x = 0; x < width; x++) {
        var t = (x * mtndetail3) + (millis() * mtnspeed3);
        var y = map(noise(t), 0, 1, 0, height * 2);
        line(x, y, x, height);
    }
    endShape();
    pop();

}

//draws car windows, frame, and handle detail 
function displayCarWindow(){
    //car window and frame display 
    push();
    stroke(40, 40, 40);
	strokeWeight(150);
	line(-30, 100, 150, 0);
	strokeWeight(100);
	line(150, 15, 480, 0);
	line(0, 430, 480, 430);
    strokeWeight(70);
    stroke(40, 50, 50);
    line(0, 450, 480, 450);
    noStroke();
    fill(255, 220, 210);
    triangle(0, 40, 0, 100, 50, 50);
    //car handle and details 
    fill(70, 70, 70);
    rect(30, 415, 120, 90);
    triangle(150, 415, 150, 480, 210, 480);
    fill(50, 50, 50);
    rect(40, 425, 90, 60);
    fill(80, 90, 80);
    push();
    fill(80, 90, 80);
    strokeWeight(20);
    stroke(80, 90, 80);
    curve(40, 430, 60, 445, 120, 440, 150, 470);
    pop();
    pop();
}

//draws car mirror 
function displayCarMirror(){
    push();
    noStroke();
    fill(240, 240, 240, 190);
    rect(0, 310, 100, 40);
    rect(0, 340, 120, 10);
    rect(0, 360, 40, 20);
    pop();
    push();
    strokeWeight(25);
    stroke(40, 40, 40);
    fill(40, 40, 40);
    curve(5, 316, 5, 316, 95, 314, 95, 400);
    curve(30, 320, 103, 318, 103, 355, 35, 359);
    curve(5, 410, 5, 380, 100, 365 - 10, 100, 290);
    pop();
}






For this week’s project, I decided to the view from a car window in the passenger seat, because roadtripping and looking out the windows is one of my favorite views in the whole world (especially in woodsy, mountainous areas). Originally, I had envisioned making telephone poles and clouds to go along with the scenery, however, after playing around with the noise function, I discovered a very pleasing wave that forms when dialing down the speed and detail aspects. I thought this form was very similar to the feeling of sticking your hand out the car window on the highway and having it glide and ride the air, but I also thought it also waved in a manner similar to rolling up and down a car window, so I implemented it as the latter. I originally wanted to implement a reflective, smaller, moving generative landscape mirroring the current on in the small car side mirror, but I could not end up figuring it out; I would like to revisit that concept when I have more time in the future.

original idea

Vicky Zhou – Looking Outwards – 09

For this week’s looking outwards post, I found my fellow peer, Jason Zhu’s Looking Outward from week 1 quite interesting. The project he discussed is Colorspace, “an interactive sculpture that translates text messages into breathtaking animations of colored light.” He pointed out that this kind of interactive space could be used in “spaces where users have a lack of or no emotional connection to, but spend a significant portion of their time”, and/or schools and and workplaces. My main question would be though, aside from creating an interest for the first couple of interactions, how else could this environment be beneficial? For example, instead of just creating a sense of community and momentary interest, could this kind of interactive digital media be used to facilitate learning, if placed in a school environment, or help engage productivity, in placed in a work environment? In addition, I personally thought of a hospital, when Jason mentioned placing this installation in a space where people typically do not feel as connected and/or emotional to, and if that could possibly shift the user into having a more positive experience.

Vicky Zhou – Project 09 – Computational Portrait

sketch

/*Vicky Zhou
Section E 
vzhou@andrew.cmu.edu
Project-09-Computational Portrait*/


var maandpa;

function preload() {
    var myImage = "https://i.imgur.com/2z2nvGR.jpg";
    maandpa = loadImage(myImage); //image of my mom and dad 
}


function setup() {
    createCanvas(350, 370);
    background(140, 200, 200, 100);
    imageMode(CENTER);
    maandpa.loadPixels();
    frameRate(900);
}


function draw() {
    var x = 1;
    var y = 1;
    var xvel = random(1, 400); //random x to add to x position 
    var yvel = random(1, 400); //random y to add to y position 
    x += int(x * xvel);
    y += int(y * yvel);


    var pcol = maandpa.get(x, y); //getting pixel color 
    noStroke();
    tint(255, 100); //makes a white tint; half opacity 
    fill(pcol);
    var size = random(0, 10); //generating random ellipse sizes 
    ellipse(x, y, size, size);

    //creating chinese word for mom on mom's side 
    if (x >= 200 & x <= 350){
        tint(255, 150);
        textSize(random(0, 20));
        text("妈", x, y);
    }
    //creating chinese word for dad on dad's side 
    if (x >= 0 & x <= 200){
        tint(255, 150);
        var space = random(0, 30);
        text("爸", x + space, y);
    }
}





For this computational portrait project, I used a cool hip photo of my momma and papa from their ol’ days. I loved seeing other people manipulate different types of text and utilizing it as their generative pixels, and so I wanted to do the same but by using the Chinese word for “mom” and “dad” on their respective side of the image. I also included ellipses to add more to the background, because I did not like it as much with the gaps. Both text and ellipses are generated to have a certain tint, to create a better layering effect, and also are generate to be of varying random sizes.

Original Image:

Generative Image:

Vicky Zhou – Looking Outwards – 08

Mouna Andraos is a co-founder of Daily Tousles Jours — a design studio that explores storytelling and collaboration of environments through technology. Mouna’s studio is based in Montreal, and she holds a Masters degree from New York University’s Interactive Telecommunications Program (ITP), and a Bachelors degree from Concordia University, In addition to running her design studio, she is also currently teaching at Concordia University and UQAM’s École de Design.

The works of Daily Tousles Jours utilizes many forms of technology, such as sensors, phones, real-time and interactive data, and physical prototypes to encourage and facilitate collaboration and performance in public spaces. For example, one of their best known works is “21 Balançoires”, which is set up yearly in Quartier des Spectacles in Montreal. “21 Balançoires” is a row of 21 swings that span down a popular sidewalk in the middle of the city. Each swing plays a different note when in motion, and thus a melody is created when several people are collaboratively swinging together. I really admire this sort of interactive installation because it encourages users of all ages, demographics, backgrounds, etc. to come together and create an experience that would never be able to be created alone.

Throughout their presentation, Mouna and Melissa Mongiat provide thorough definitions for words at the start of major concepts and/or ideas they present, and also provide a lot of interesting videos and visualizations of what their projects encompass. I feel like these are effective in communicating their ideas, especially since their projects often touch upon several different thresholds, mediums, and materials.

Daily Tousles Jours Website