Alice Fang – Project 7

click me!

/*
Alice Fang
Section E
acfang@andrew.cmu.edu
Project-07-Curves
*/

// http://mathworld.wolfram.com/EightCurve.html  

// click to begin! and keep clicking to see it change! 

var nPoints = 100;
var clickCount = 0;

function setup() {
    createCanvas(400, 400);
    frameRate(10);
    strokeWeight(3);
    noFill();
}

function draw() {
    background(0, 128, 128);
    var rad; // scale of expansion (how much wider the petal becomes)
    var angle; // angle of rotation the curve is translated

    for (i = 0; i < clickCount; i++) {
    	rad = 0.1 * i; // becomes wider with every click
    	angle = 30 * i; // rotates with every click
    }

    // curve in top right corner
    push();
    translate(3 * width / 4, height / 4);
    rotate(radians(angle + 45));
    drawCurve(random(0, 255), rad); //random color, angle
    pop();

    // curve in bottom left corner
    push();
    translate(width / 4, 3 * height / 4);
    rotate(radians(angle + 45));
    drawCurve(random(0, 255), rad);
    pop();

    // curve in top left corner
    push();
    translate(width / 4, height / 4);
    rotate(radians(angle - 45));
    drawCurve(random(0, 255), rad);
    pop();

    // curve in bottom right corner
    push();
    translate(3 * width / 4, 3 * height / 4);
    rotate(radians(angle - 45));
    drawCurve(random(0, 255), rad);
    pop();

    // center curve
    push();
    translate(width / 2, height / 2);
    rotate(radians(angle + 90))
    drawCurve(random(0, 255), rad);
    pop();

    // perpendicular center curve
    push();
    translate(width / 2, height / 2);
    rotate(radians(angle));
    drawCurve(random(0, 255), rad);
    pop();
   
}

// draw eight curve
function drawCurve(c, r) {
    var x;
    var y; 
    var a = constrain(mouseX, 0, width / 2);
    
    stroke(c);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI); // map to unit circle

        // parametric function
        x = a * sin(t); 
        y = a * sin(t) * cos(t) * r;

        vertex(x, y);
    }
    endShape(CLOSE);
}

function mousePressed() {
	clickCount++;
}

I struggled a lot with this project in particular, because I forgot a lot of the algebra related. I found it really difficult to implement any curve at all, and I originally wanted to use a more complicated curve. However, I enjoy the simplicity of this curve and how complex it can become when layered on top of each other. This reminds me of tangled strings, especially the more you click and zoom in! The greyscale flickering happened on accident, but I really liked it so I kept it, moving away from the filled hour-glass shapes I had originally.

Playing around with fill; I like how this one looks like a round square!

A starting position; curve with width 0

Looks like string!

Zooming out from the previous screenshot

Interesting patterns form when they overlap at certain zoom levels

Alice Fang – Looking Outwards – 07

A screenshot of the article
View of the entire storm, from the article

The New York Times published an interactive 3-dimensional map of the recent Typhoon Mangkhut, which slammed into the Philippines and south Asia mid-September this year. A combination of informational text, and visualization of rainfall and scale of the storm, the map changes as a user scrolls down the screen. Using data from a NASA satellite, the graphic takes advantage of scrolling down to zoom in and out of the storm, which is further broken down into squares or pixels, with red representing the most intense rainfall and blue representing the lightest rain. Produced by Yuliya Parshina-Kottas ,Karthik Patanjali, Jeremy White, Benjamin Wilhem, and Jon Huang, this visualization maps data sets from NASA into points in 3-D space, using color to represent concentration. This is most likely similar to the map function in p5, in order to translate one range into another. I’d like to know how to interact with objects beyond just an x-y plane, and I really enjoy the interaction with this specific data visualization.

Alice Fang – Project 6 – Abstract Clock

sketch

/*
Alice Fang
acfang@andrew.cmu.edu
Section E
Project-06-AbstractClock
*/

function setup() {
    createCanvas(400, 400);
    noStroke();
}
function draw() {
	background(146, 211, 231);

	//current time
	var H = hour();
	var M = minute();
	var S = second();

	// sun
	var arc = 140; // radius of sun trajectory path
	var angle = H;
	push();
	translate(width/2, height/2);
	rotate(radians(7.5*H)); // rotate based on time of day, with highest point at 12:00 pm
	fill(239, 244, 214);
	ellipse(0 - arc, 0, 36, 36);
	pop();

	//static landscape
	fill(145, 168, 113); // farthest mountain
	beginShape();
	vertex(0, 166);
	vertex(67, 186);
	vertex(115, 175);
	vertex(150, 182);
	vertex(240, 152);
	vertex(270, 160);
	vertex(328, 144);
	vertex(352, 153);
	vertex(369, 150);
	vertex(400, 157);
	vertex(400, 400);
	vertex(0, 400);
	endShape(CLOSE);

	fill(125, 147, 96); //third mountain
	beginShape();
	vertex(0, 226);
	vertex(40, 208);
	vertex(95, 224);
	vertex(183, 205);
	vertex(288, 218);
	vertex(400, 186);
	vertex(400, 400);
	vertex(0, 400);
	endShape(CLOSE);

	fill(81, 110, 81, 80); // second mountain
	beginShape();
	vertex(0, 266);
	vertex(20, 258);
	vertex(40, 265);
	vertex(110, 244);
	vertex(200, 275);
	vertex(260, 312);
	vertex(400, 323);
	vertex(400, 400);
	vertex(0, 400);
	endShape(CLOSE);

	fill(81, 110, 81, 80); // closest mountain
	beginShape();
	vertex(0, 280);
	vertex(47, 298);
	vertex(77, 289);
	vertex(119, 330);
	vertex(175, 348);
	vertex(211, 326);
	vertex(288, 337);
	vertex(325, 370);
	vertex(400, 400);
	vertex(0, 400);
	endShape(CLOSE);
 
 	// hot air balloon!
	var mapY1 = map(S, 0, 60, height, -175); // map y position of turquoise balloon to seconds
	var mapY2 = map(M, 0, 60, height * 2, -175); // map y position of magenta balloon to minutes
	var mapY3 = map(H, 0, 24, height * 2.857, -175); // map y position of orange balloon to hours
	var balX = 300; // X position of balloon
	var balY1 = mapY1;
	var balY2 = mapY2;
	var balY3 = mapY3;

	drawBalloon(balX, balY1 + 60, 120, 1, 26, 120, 142); // turquoise balloon
	drawBalloon(balX, balY2 + 60, 120, 0.5, 137, 62, 101); // magenta balloon
	drawBalloon(balX - 100, balY3 + 60, 120, 0.35, 233, 153, 95); // orange balloon

	if (H <= 11 & H >= 6) {
		fill(252, 217, 192, 75) // morning color
		rect(0, 0, width, height);
	} else if (H >= 14 & H <= 20) {
		fill(228, 77, 46, 75); // sunset color
		rect(0, 0, width, height);
	} else if (H > 20 || H < 6) {
		fill(5, 6, 90, 99); // dusk color
		rect(0, 0, width, height);
	}
}

function drawBalloon(balX, balY, balSize, balScale, R, G, B) {
	push();
	scale(balScale);
	fill(R, G, B);
	ellipse(balX, balY, balSize, balSize); // balloon shape
	quad(balX - 44, balY + 40, balX + 44, balY + 40, balX + 14, balY + 77, balX - 13, balY + 77);
	
	stroke(0); // basket lines
	line(balX - 12, balY + 77, balX - 12, balY + 90);
	line(balX + 12, balY + 77, balX + 12, balY + 90);
	noStroke();
	
	fill(104, 81, 32); // basket
	rect(balX - 12, balY + 90, 25, 25);
	pop();
}

Concept sketch
Illustrator concept; morning
Illustrator concept; evening
Illustrator concept; dusk

I was inspired by some photographs that I saw of hot air balloons, and I really wanted to play with the different colors of sky at different times of day. The trickiest parts for me were setting up the function drawBalloon() to create the balloons, because once I scaled them, I forgot what variables would be affected in terms of animation.

The largest, turquoise balloon represents seconds, with the magenta balloon as minutes and the orange balloon as hours. The sun also rises and sets based on the hour, with the highest point at noon.

Alice Fang – Looking Outwards – 06

Poultri, generated on February 2, 2015
A conversation, generated on September 29, 2018

smiling face withface is a Tumblr-bot that was created by Allison Parrish, a computer programmer, poet, educator and game designer who currently teaches at NYU’s Interactive Telecommunications Program. smiling face generates and posts glitchy emoticons, pulling randomly from the open-source SVG files from Twitter’s twemoji project. The randomness, in this case, is obtained from a set data source (Twitter’s emojis, of which there are 2841) , and a Python program adjusts the numbers and paths from the emoji taken. The results are strange amalgamations that are fun, quirky, and very colorful, and most of the time, nearly unrecognizable from the original source. Personally, I think the glitchy-ness makes viewing these emojis more interesting, if sometimes uncomfortable, because you know what it is but there’s something that’s slightly off. Many of them make me laugh, and the project is still ongoing into October 2018, so there’s more to look forward to!

Alice Fang – Project 5 – Wallpaper

sketch

/*
Alice Fang
Section E
acfang@andrew.cmu.edu
Project-05-Wallpaper
*/

var citrusSize = 80;

function setup() {
    createCanvas(600, 600);
    background(176, 196, 222);
    noStroke();
}

function draw() {
	var offset = 5; // offset for fruit outlines

	// draw oranges
	for (x = 75; x < width; x += 150){ 
		for (y = 75; y < height; y += 150){
			noStroke();
			fill(244, 164, 96); 
			ellipse(x, y, citrusSize, citrusSize);

			// orange outline
			noFill();
			strokeWeight(5);
			stroke(220, 120, 30);
			ellipse(x + 5, y + 5, citrusSize, citrusSize);

			// orange dot details
			point(x + 20, y - 20);
			point(x + 15, y - 15);
			point(x + 10, y - 20);
		}
	} 
	var citrusX = 150; // width between lemon and lime
 	var citrusY = 150; // height between rows of lemon/lime
 	textStyle(ITALIC);

	// draw lemon and lime wedges
	for (x = 0; x < 6; x++) {
		for (y = 0; y < 5; y++) {
			var px = x * citrusX; // horizontal spacing between wedges
			var py = y * citrusY + 10; // vertical spacing between wedges
			
			if (x % 2 == 1) { // lemon wedges for even columns
				noStroke(); 
				fill(255, 250, 205);
				arc(px, py, citrusSize, citrusSize, 0, PI);
				
				fill(240, 230, 140); // lemon wedge shading
				triangle(px, py+5, px+5, py+30, px-10, py+30);
				triangle(px+2, py, px - 40, py + 10, px-35, py + 25);
				triangle(px+2, py, px+15, py + 30, px+30, py+10);

				text("lemon", px-10, py-50);
			}
			else { // lime wedges for odd columns
				noStroke();
				fill(154, 190, 20); 
				arc(px, py, citrusSize, citrusSize, 0, PI);
			
				fill(200, 255, 80); // lime wedge shading
				triangle(px, py+5, px+5, py+30, px-10, py+30);
				triangle(px+2, py, px - 40, py + 10, px-35, py + 25);
				triangle(px+2, py, px+15, py + 30, px+30, py+10);

				text("lime", px-10, py-50);
			}
			noFill();
			strokeWeight(5); // offset outline (citrus rind)
			stroke(255, 215, 10);
			arc(px - offset, py - offset, citrusSize, citrusSize, 0, PI);
		}
	}
	noLoop();	
}

This was inspired by a pajama set that I own, and my own affinity for citrus prints (I also own a tshirt that has a different style of citrus illustration). For some reason, I’m drawn to these fruits, and I thought it would be an interesting way to combine the two different citrus clothing that I own. It was definitely good practice in nested loops, and getting more familiar with the % operator, since I wrote the lemons and limes separately before deciding to combine them into a nested for loop.

The pajama set with lemons and other fruit
Explorations of citrus illustration

Alice Fang – Looking Outwards – 5

HBO Westworld – Main Titles from Elastic on Vimeo.

Elastic is a company that produces advertisements, main titles for TV shows and movies, animations, broadcasts, and other video production. I really like this video, which is the main title they produced for the first season of HBO’s Westworld. (They also produced the main title for the second season as well. It’s on their website!) A team of CG artists, motion graphic artists, and designers, under creative director Patrick Clair, painstakingly built sets and models digitally. The programs they used include ZBrush, Cinema 4D, Maya, AfterEffects, and Octane. Through this, Elastic rendered and modelled 3-D assets that reflected the wild west, distorted human robotic symbiosis. Watching this in isolation always gives me the chills, especially with the music composed by Ramin Djawadi. The music and the scenes tie together to create an eery feeling, and I find the detail in the rendering to hit close to the uncanny valley (a point where realisim in androids makes a very unsettling affect).

Alice Fang–Project 04–String Art

sketch

/*
Alice Fang
Section E
acfang@andrew.cmu.edu
Project-04
*/

var x1; // (x1, y1, x2, y2) variables for lines
var y1;
var x2;
var y2;

var circlesize = 270; // circle diameter
var squaresize = 80; // square length

function setup() {
    createCanvas(400, 300);
    background(0);
    
}
function draw() {
    stroke(57, 255, 20);
    strokeWeight(0.5);

    // bottom left corner curve
    for (var i = 0; i < width; i += 20) {
        x1 = i;
        y1 = height; 
        y2 = i;
        x2 = 0; 
        line(x1, y1, x2, y2);
    }

    // top right corner curve
    for (var i = width; i > 0; i -= 20) {
        x1 = i + width - 300;
        y1 = 0; 
        y2 = i;
        x2 = width; 
        line(x1, y1, x2, y2);
    }

    //bottom right corner curve
    push();
    translate(width / 4, height);
    rotate(radians(270));
    for (var i = 0; i < width; i += 20) {
        x1 = i;
        y1 = height; 
        y2 = i;
        x2 = 0; 
        line(x1, y1, x2, y2);
    }
    pop();

    //top left corner curve
    push();
    translate(0, height + width / 4);
    rotate(radians(270));
    for (var i = width; i > 0; i -= 20) {
        x1 = i + width - 300;
        y1 = 0; 
        y2 = i;
        x2 = width; 
        line(x1, y1, x2, y2);
    }
    pop();

    // center square outline
    noFill();
    rect(width / 2 - 40, height / 2 - 40, squaresize, squaresize);

    // white circle outlines 
    stroke(240);
    ellipse(width / 2, height / 2, circlesize, circlesize);
    ellipse(width / 2, height / 2, 115, 115);
    ellipse(width / 2, height / 2, circlesize / 15, circlesize / 15);

    fill(240);
    ellipse(width / 2, height / 2, circlesize / 27, circlesize / 27);

    // curves generated in square
    noFill();
    strokeWeight(0.5);
    stroke(57, 255, 20);

    push(); // translate (0, 0) to top left corner of square
    translate(width / 2 - squaresize/2, height / 2 - squaresize/2);
    square(0, 0); // top X shape (function square() established below)

    push();
    translate(0, squaresize); // left X shape
    rotate(radians(270));
    square(0, 0);
    pop();

    push();
    translate(squaresize, 0); // right X shape
    rotate(radians(90));
    square(0, 0);
    pop();

    push(); 
    translate(squaresize, squaresize); // bottom X shape
    rotate(radians(180));
    square(0, 0);
    pop();

    pop();
    
    // cross hair (white perpendicular lines)
    stroke(255);
    line(width / 2, 0, width / 2, height);
    line(0, height / 2, width, height / 2);
}

function square(x, y){ // produces X-shape within square
        push();
        translate(x, y);
        noFill();
        strokeWeight(0.5);
        stroke(57, 255, 20);
        for (i = 0; i < 30; i+=10) {
            x1 = 0;
            x2 = squaresize;
            y1 = .75*i + 20;
            y2 = -i + 20;
            line(x1, y1, x2, y2);
            line(x2, y1, x1, y2);
        }
        pop();
}    

This was inspired by lasers that my mind associates with laser security systems, as well as eye-scanning mechanisms. (Or perhaps, a target scope aimed at an eye? They’re all interpretations within the same realm). The color scheme of neon green and black were especially influenced by this. I also used this project as an opportunity to try out and practice defining and creating my own function.

Alice Fang–Looking Outwards–4


Turbulent Forms

Dan Tapper is a British artist who combines code with his interest in celestial bodies and objects in the universe. The second iteration of his project Turbulent Forms is in collaboration with the Canadian Music Centre, and is a sonification of cosmic phenomena. Using abstract ideas of space and chaos, Tapper created software that generated modulated “sine tones of various pitches” and then collaborated with various artists and composers to create a composition. In total, six songs were produced, and performed at a NOVA concert.

While listening to the pieces, I was immediately reminded of the scores produced for the movie Interstellar, and it’s interesting how the generated pitches and almost mechanized sounds lend themselves to imagery of being in space. The general concept of the music is to “collectively simulate motions of bodies being pulled into the influence of a black hole” and that feeling of nothingness, of tension and anxiety, are definitely captured by the different pieces. I also think it’s really interesting that some of the artists actually pulled from NASA recordings as source material, creating an ambience that is very reminiscence of space.

Read more about this collaborative project!

Alice Fang–Project 03– Dynamic Drawing

sketch

/*
Alice Fang
Section E
acfang@andrew.cmu.edu
Project-03
*/

/*
When mouseX is > width/2, 
	-magenta circle shrinks while cyan circle grows
	-blue circle rotates clockwise, yellow circle couterclockwise

When mouseX is < width/2,
	-magenta circle grows while cyan circle shrinks
	-blue circle rotates counterclockwise, yellow circle clockwise

When mouseX is within the red circle
	-green circle rotates clockwise
	-green circle becomes smaller
	-green circle rotates more quickly
	-things become dark! goodbye light

Sometimes there is a delay with the growth/shrink of magenta and cyan circles-
neither I nor Prof. Dannenberg know exactly why 🙁 */

//circle diameters
var yellowD = 100;
var cyanD = 80;
var redD = 240;
var greenD = 80;
var magentaD = 320;
var blueD = 160;

var scale1 = 5; //constant rate of growth for cyan/magenta circles
var scale2 = -5; //constant rate of shrinking for cyan/magenta circles

//rotataion speed
var angle1 = 0; //blue circle
var angle2 = 0; //yellow circle
var angle3 = 0; //green circle (mouseX inside red circle)
var angle4 = 0; //green circle (mouseX outside red circle)
var angle5 = 0; //cyan circle
var angle6 = 0; //magenta circle

function setup() {
    createCanvas(640, 480);
    noStroke();
    
}

function draw() {
	background(255);

	if (dist(160, 280, mouseX, mouseY) < redD/2) {
		background(0); //switch background to black
	} else {
		background(255); 
	}

	var cyanS = constrain(cyanD, 40, 500); //limit growth of cyan
	var magentaS = constrain(magentaD, 40, 500); //limit growth of magenta
	
	if (mouseX > width / 2) {
		cyanD += scale1; //cyan increases in size
		magentaD += scale2; //magenta decreases in size
		angle1 += 5; //blue rotates clockwise
		angle2 -= 3; //yellow rotates counterclockwise
	} 
	if (mouseX < width /2) {
		cyanD += scale2; //cyan decrease in size
		magentaD += scale1; //magenta increase in size
		angle1 -= 3; //blue rotates counterclockwise, decreases speed 
		angle2 += 5; //yellow rotates clockwise, increases speed 
	}

	//cyan circle
	push();
	translate(width/2, height/2); 
	rotate(radians(angle5));
	angle5 -= 1; //rotation speed
	fill('rgba(0, 255, 255, 0.5)'); 
	ellipse(200, 160, cyanS, cyanS);
	pop();

	//magenta circle
	push();
	translate(width/2, height/2);
	rotate(radians(angle6));
	angle6 += 1; //rotation speed, 
	fill('rgba(255, 0, 255, 0.5)'); 
	ellipse(80, 40, magentaS, magentaS);
	pop();

	//red circle
	if (dist(160, 280, mouseX, mouseY) < redD/2) { //if mouse is inside red circle
		fill('rgba(0, 0, 0, 0.7)'); //become black
		ellipse(160, 280, redD, redD);
	} else {
		fill('rgba(255, 0, 0, 0.7)');
		ellipse(160, 280, redD, redD);
	}

	//blue circle
	push();
	translate(360, 240);
	rotate(radians(angle1));
	ellipseMode(CORNER);
	fill('rgba(0, 0, 255, 0.5)'); 
	ellipse(0, 0, blueD, blueD);
	pop();

	//yellow circle
	push();
	translate(360, 240);
	rotate(radians(angle2));
	ellipseMode(CORNER);
	fill('rgba(255, 255, 0, 0.7)');
	ellipse(80, 80, yellowD, yellowD);
	pop();

	//green circle
	if (dist(160, 280, mouseX, mouseY) < redD/2) { //if mouse is inside red circle
		push();
	    translate(160, 280);
	    rotate(radians(angle3));
	    angle3 += 8; //rotation speed, clockwise
	    fill('rgba(0, 255, 0, 0.7)');
	    ellipse(180, 0, greenD/2, greenD/2);
	    pop();
	} else { 
		push();
		translate(160, 280);
		rotate(radians(angle4));
		angle4 += -1; //rotation speed, counterclockwise
		fill('rgba(0, 255, 0, 0.7)'); 
	    ellipse(180, 0, greenD, greenD);
	    pop();
	}

	textSize(20);
	fill(255);
	if (dist(160, 280, mouseX, mouseY) < redD/2) { //if mouse is inside red circle
		text("goodbye!", mouseX, mouseY);
	} else {
		text("hello!", mouseX, mouseY);
	}
}

For this project, I was inspired by the RGB overlay. Originally, I wanted to set a condition where if two circles overlapped, the intersection would fill white, as would happen if you overlay-ed real RGB values. In the end, I decided to create something that was bright and bubbly, playing with opacity and color.

RGB colors! My inspiration for this project.

Also, a quick note. I sort of mentioned this in the comments, but nothing is random. Everything is dependent on the position of mouseX relative to the canvas (width/2), or to the red circle. The growth of the cyan and magenta circles lag a little, but will respond.

Alice Fang – Looking Outwards – 03

Vespers, Series 2, Mask 5. Bottom View. 2016. Photo: Yoram Reshef
Vespers, Series 2, Mask 5. Close-up view.

Vespers: Series II is the second of a three-part series produced by the Mediated Matter group at MIT’s Media Lab that explores how designing masks relates to “design (with) life.” This part examines the transition between life and death, and marks a progression from the first part of the project- looking at death masks as a cultural object- to the third part- using death masks as a “functional biological interface.” A theme that surrounds this second part is the idea of metamorphosis, moving from a symbol of life and death to the concept of wearable skins and interfaces.

The structures of these masks are designed to match actual biological structures observed in nature, and spatial mapping algorithms are used to translate color and geometry from the first part of the series into internal structures in this second part. Each mask also has a unique dataset that informs the distribution of the materials in its print.

I admire how a concept so abstract as this can create objects that are so detailed and delicate-looking from computer generation. It amazes me that these were 3-D printed, but I suppose 3-D printing has evolved so much in the past few years, where glass and porcelain can be printed now too. It’s also very interesting conceptually, to consider how the idea of life and death can transform into a technological and biological tool for skins and surfaces.