//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project 07 - Curves
var nPoints = 200;
var rotation = 0; //rotation for all Hypotrochoid Evolutes starts at 0
function setup() {
createCanvas(480, 480);
}
function draw() {
background('white');
stroke('white');
//Hypotrochoid Evolutes:
drawHypotrochoidEvolute(5, 300, 0.75, 2.5, color(139, 198, 63, 125)); //green
drawHypotrochoidEvolute(10, 150, map(mouseX, 0, width, 0, 2), 1.5, color(173, 18, 26, 125)); //red
drawHypotrochoidEvolute(5, 200, map(mouseY, 0, height, 0.25, 1), 2.5, color(177, 158, 219, 125)); //purple
drawHypotrochoidEvolute(50, 150, map(mouseY, height, 0, 0, 2), 1.5, color(113, 198, 232, 125)); //blue
drawHypotrochoidEvolute(25, 226, map(mouseX, width, 0, 0.25, 1.5), 2, color(253, 185, 63, 125)); //yellow
}
function drawHypotrochoidEvolute(pedalNum, angularity, size, strokeW, fillColor) { //pedalNum and angularity affect how many "pedals" you see, and their appearance
// Hypotrochoid Evolute:
// http://mathworld.wolfram.com/HypotrochoidEvolute.html
push();
translate(width / 2, height / 2);
scale(size); //scales down Hypotrochoids (including stroke), specified under draw
//causes all Hypotrochoid Evolutes to rotate at same rate, clockwise when mouse is below the middle of the canvas, counter-clockwise when above
rotation += map(mouseY, 0, height, -TWO_PI / 800, TWO_PI / 800);
rotate(rotation);
//creates the Hypotrochoid Evolutes
beginShape();
fill(fillColor);
strokeWeight(strokeW);
for (var i = 0; i < nPoints; i++) {
var t = map(i, 0, nPoints, 0, TWO_PI);
var h = map(mouseX, 0, width, -200, 200);
//The equation for Hypotrochoid Evolutes
x = (angularity - pedalNum) * cos(t) + h * cos((angularity - pedalNum) * (t / pedalNum));
y = (angularity - pedalNum) * sin(t) - h * sin((angularity - pedalNum) * (t / pedalNum));
vertex(x, y);
}
endShape();
pop();
}
When approaching this project, I was a little overwhelmed, as I didn’t really know where to start, but after looking through the different roulette curves on the Mathworld curves website, I chose to focus on just the hypotrochoid evolute forms, as there were a large range of forms and examples for that particular curve that I could explore. After playing around with them a little, I started experimenting with colors and transparencies, and tried to go in the direction of a kaleidoscope, as I wanted my project to be constantly changing, and to reveal/conceal the different layers of colors depending on the location of your mouse.
This week, I chose to look at Stefanie Posavec’s art.park.data, a 32.5m long data visualization drawing in Queen Elizabeth Olympic Park, created from data collected by students participating in Space Studios’ “School’s (Not Quite) Out for Summer.” The students, who were from the nearby neighborhoods, and transitioning from elementary to middle school, explored the park with Raspberry Pis fitted with special sensor Hardware Attached on Top (HATs), in order to collect data like the latitude and longitude of their locations, the humidity and temperature, the sounds they heard, the types of plants around them, and even the emotions they felt in that place.
I particularly admire this project, as the students were able to explore the park, make observations, write down notes, and afterwords, use arts and crafts materials to create their own personal visualizations of the data, making this experience more meaningful for the students, and centered solely around them and their perspectives. Although data visualization can sometimes seem impersonal or distant, through Posavec’s use of bright colors, graphic forms, and simple composition, she was able to create a friendly, interesting, and playful snapshot of the park through the eyes of the children who visit it.
While not directly involving coding, the project that I chose to look at for this week is Tim Knowles’ Windwalks. Tim Knowles is a British artist based in London, and his project, Windwalks, visualizes a series of walks directed only by the wind using different mechanisms. Each walk is filmed, and then plotted by GPS, with the end product a line drawing of the path the individual took.
I found this project particularly interesting, because it incorporates randomness in the form of the wind. While the wind is biased in the sense that there are trends and currents that the wind follows, this factor combined with the individual’s environment ends up generating a unique and personal piece of art. Not only does this project visualize an activity that we often overlook in our day to day lives, walking, it also reveals the outlines of buildings, cars, and objects in the environment, as individuals, prompted by the direction of the wind, collide with the structures of the city, making them visible in a new light. Thus, Knowles is able to create new, different, and deeper relationships between individuals, their cities, and the wind itself.
//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project 06, Abstract Clock
var islandX = 240; //starting X coordinate of island center
var islandY = 210; //y coordinate of island center, stays constant
var islandHalfWidth = 75;
var islandH = 100; //tallest height of island mountain
var islandSpeed = 0.001; //controls the lag of island movement
var sheepSpeed = 0.01;
var gearWidth = 12; //the radius of the gear (represents radius of inner "circle")
var gearThick = 2;
var sheepW = 20;
var sheepH = 15;
var sheepHeadW = 8;
var sheepHeadH = 12;
var ear = 4; //size of sheep ear ellipse
var eye = 2; //size of sheep eye ellipse
var sheepX = 0;
function setup() {
createCanvas(480, 480);
rectMode(CENTER);
angleMode(DEGREES);
}
function draw() {
background(220);
var h = hour(); //24 hour clock
var m = minute();
var s = second();
difisland = islandX - mouseX;
islandX = constrain(islandX, islandHalfWidth * 3, width - islandHalfWidth * 3) + difisland * islandSpeed; //causes the island to move slowly to mouse position
//sky, fades as time changes
colorMode(HSB, 100); //change color mode in order to help with darkening/lightening the sky
if (h > 18 & h < 24 || h > -1 && h < 6) {
b = 15;
}if (h > 5 & h < 13) {
b = 15 + (h * 7);
} if (h > 11 & h < 19) {
b = 99 - ((h - 12) * 7);
}
c = color(55, 60, b);
fill(c);
rect(width / 2, height / 2, width, height);
//ground
colorMode(RGB); //switch back to RGB from HSB
fill(92, 147, 13);
rect(width * 0.5, height - 25, width, 50);
//mountain on island
stroke(92, 147, 13);
fill(92, 147, 13);
strokeWeight(14);
strokeJoin(ROUND);
beginShape(); //vertices that form the mountain
vertex(islandX - islandHalfWidth, islandY);
vertex(islandX - islandHalfWidth * 0.3, islandY - islandH * 0.75);
vertex(islandX - islandHalfWidth * 0.1, islandY - islandH * 0.6);
vertex(islandX + islandHalfWidth * 0.2, islandY - islandH);
vertex(islandX + islandHalfWidth * 0.65, islandY - islandH * 0.3);
vertex(islandX + islandHalfWidth * 0.8, islandY - islandH * 0.3);
vertex(islandX + islandHalfWidth, islandY);
vertex(islandX - islandHalfWidth, islandY);
endShape();
//door in mountain
var doorH = 45
noStroke();
fill(58, 109, 29);
rect(islandX - islandHalfWidth * 0.3, islandY - doorH * 0.5, 20, doorH, 15, 15, 0, 0);
noStroke(); //door knob
fill(44, 84, 41);
ellipse(islandX - islandHalfWidth * 0.375, islandY - doorH * 0.5, 3, 3);
//window in mountain
var winHalfLength = 25 * 0.5 //radius of window
if (h > 7 & h < 19) {
fill(58, 109, 29);
ellipse(islandX + islandHalfWidth * 0.2, islandY - islandH * 0.5, 25, 25);
} else { //makes the window glow yellow when it's "dark" outside
fill(255, 197, 68);
ellipse(islandX + islandHalfWidth * 0.2, islandY - islandH * 0.5, 25, 25);
}
stroke(44, 84, 41);
strokeWeight(3); //bars of the window:
line((islandX + islandHalfWidth * 0.2) - winHalfLength, islandY - islandH * 0.5, (islandX + islandHalfWidth * 0.2) + winHalfLength, islandY - islandH * 0.5);
line(islandX + islandHalfWidth * 0.2, (islandY - islandH * 0.5) - winHalfLength, islandX + islandHalfWidth * 0.2, (islandY - islandH * 0.5) + winHalfLength);
//underneath the island
stroke(44, 84, 41);
fill(44, 84, 41);
strokeWeight(18);
beginShape(); //vertices that form the underside
vertex(islandX - islandHalfWidth, islandY);
vertex(islandX - islandHalfWidth * 0.75, islandY + islandH * 0.4);
vertex(islandX - islandHalfWidth * 0.5, islandY + islandH * 0.5);
vertex(islandX - islandHalfWidth * 0.3, islandY + islandH * 0.75);
vertex(islandX - islandHalfWidth * 0.1, islandY + islandH * 0.85);
vertex(islandX + islandHalfWidth * 0.2, islandY + islandH * 0.6);
vertex(islandX + islandHalfWidth * 0.5, islandY + islandH * 0.5);
vertex(islandX + islandHalfWidth * 0.65, islandY + islandH * 0.3);
vertex(islandX + islandHalfWidth * 0.8, islandY + islandH * 0.25);
vertex(islandX + islandHalfWidth, islandY);
vertex(islandX - islandHalfWidth, islandY);
endShape();
//gear, rotates every second
push();
strokeWeight(2);
stroke(255);
translate(islandX + islandHalfWidth * 0.99, islandY + islandH * 0.1);
for (var g = 0; g < 60; g ++) {
if (g > s || g < s) {
push();
rotate(180 + g * 6);
line(0, gearWidth, 0, gearWidth + gearThick);
pop();
} else { //highlights the second hand on the gear
push();
stroke(124, 17, 17);
rotate(180 + g * 6);
gearMiddle(0, 0); //rotates the center cutouts of the gear
line(0, gearWidth, 0, gearWidth + 2 * gearThick); //the second hand
pop();
}
}
pop();
//ladder, increases by one rung each minute
var ladderH = 5;
var ladderW = 15;
var ladderX = islandX - islandHalfWidth;
stroke(153, 124, 232);
strokeWeight(2);
line(ladderX, islandY - 9, ladderX, islandY);
line(ladderX + ladderW, islandY - 9, ladderX + ladderW, islandY);
for (var i = 0; i < m; i += 1) {
var ladderY = (islandY - 3) + 4 * i; //Y coordinate for the start of the ladder
if (i < 9 || i > 9 & i < 19 || i > 19 && i < 29 || i > 29 && i < 39 || i > 39 && i < 49 || i > 49) { //creates everything but the 10's
stroke(255);
line(ladderX, ladderY, ladderX + ladderW, ladderY); //the rungs of the ladder that correspond to everything but the multiples of 10
} else {
stroke(153, 124, 232);
line(ladderX, ladderY, ladderX + ladderW, ladderY); //the rungs of the ladder that correspond to every 10 minutes
}
stroke(153, 124, 232);
line(ladderX, ladderY - ladderH, ladderX, ladderY + ladderH); //left vertical rail of ladder
line(ladderX + ladderW, ladderY - ladderH, ladderX + ladderW, ladderY + ladderH); //right vertical rail of ladder
}
//text: hour, minute, second, colons
noStroke();
textSize(14);
var textX = width * 0.5;
var textY = height - 20;
var coltextdistX = 20;
var coltextdistY = 2; //adds to the Y coordinates for the colons, to visually center them vertically
fill(255);
rect(textX, textY - 5, 100, 25, 30, 30, 30, 30);
fill(255, 197, 68);
textAlign(RIGHT); //hour text
if (h < 10) {
text(nf(h, 1, 0), textX - 1.4 * coltextdistX, textY);
} else {
text(nf(h, 2, 0), textX - 1.4 * coltextdistX, textY);
}
fill(92, 147, 13);
textAlign(CENTER); //colon and minute text
text(':', textX - coltextdistX, textY - coltextdistY); //colon between hour and minute
text(':', textX + coltextdistX, textY - coltextdistY); //colon between minute and second
fill(153, 124, 232);
text(nf(m, 2, 0), textX, textY);
textAlign(LEFT); //second text
fill(124, 17, 17);
if (s < 10) {
text(nf(s, 1, 0), textX + 1.4 * coltextdistX, textY);
} else {
text(nf(s, 2, 0), textX + 1.4 * coltextdistX, textY);
}
//sheep stack
difsheep = mouseX - sheepX;
sheepX = constrain(sheepX, sheepW, (width - sheepW * 1.5)) + difsheep * sheepSpeed; //causes the sheep to move slowly to mouse position
for (var y = 0; y < h; y += 1) {
sheep(sheepX, (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));
if ((sheepX - mouseX) > 0) {
sheepHead(- sheepW * 0.25 + (sheepX * 0.5), (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));
} else {
sheepHead(sheepW * 0.25 + (sheepX * 0.5), (height * 0.95 - sheepH * 2) - (y * sheepH * 1.15));
}
}
}
//gear cutouts
function gearMiddle(x, y) { //creates the center cutouts of the gear
for (var d = 0; d < 4; d ++) {
push()
stroke(255);
strokeWeight(2);
rotate(d * 45);
line(x, y - gearWidth - 2 * gearThick, x, y + gearWidth + 2 * gearThick);
pop();
}
}
//sheep
function sheep(x, y) {
push();
translate(x, y);
stroke(0);
strokeWeight(2);
line(-sheepW * 0.25, 0, -sheepW * 0.25, sheepH * 0.6); //sheep leg left
line(sheepW * 0.25, 0, sheepW * 0.25, sheepH * 0.6); //sheep leg right
noStroke();
fill(0);
ellipse(-sheepW * 0.5, 0, ear, ear); //sheep tail left
ellipse(sheepW * 0.5, 0, ear, ear); //sheep tail right
fill(255);
stroke(255, 197, 68)
strokeWeight(1.25);
rect(0, 0, sheepW, sheepH, 15, 15, 15, 15); //sheep body
pop();
}
function sheepHead(x, y) {
push();
translate(x, y);
noStroke();
fill(0);
rect(x, y / 600, sheepHeadW, sheepHeadH, 3, 3, 15, 15); //sheep head
ellipse(x - sheepHeadW * 0.5, (y / 600) - sheepHeadH * 0.2, ear, ear); //left sheep ear
ellipse(x + sheepHeadW * 0.5, (y / 600) - sheepHeadH * 0.2, ear, ear); //right sheep ear
fill(255);
ellipse(x - 2, y / 600, eye, eye); //left sheep eye
ellipse(x + 2, y / 600, eye, eye); //right sheep eye
pop();
}
While I didn’t really explore unconventional ways to read time through this project, I tried to seamlessly embed time into a simple but fun illustration, so that it became more of an artefact, rather than something really practical. I was initially inspired by the concept of cuckoo clocks, but my clock eventually warped into a floating island. I ended up creating a 24 hour clock, where the number of sheep represent the hour, the number of rungs on the ladder represent the minute, and the gear on the island shows the seconds.
The artist I chose to write about this week is Gustavo Henrique, a 3D artist and freelancer from Brazil. I really admire not only his use of color and how he frames his work, but also the playfulness and movement he captures. Through his use of a matte finish, his forms come off as organic, friendly, and fluffy, almost as if you could make them out of clay or reach into the illustration to squish them. Moreover, by blurring the edges and forms that aren’t the main focus, his creations look like they’re miniatures, as if you took a picture of them using a high aperture on your camera. Henrique uses Cinema 4D and Octane Render to create his illustrations.
//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project-05-Wallpaper
function setup() {
createCanvas(600, 600);
background(18, 120, 161);
noLoop();
}
function draw() {
//grid background
for (var y = 0; y < height + 25; y += 50) {
for (var x = 0; x < width + 25; x += 50) {
//diagonal lines
var linelength = 25;
strokeWeight(5);
stroke(63, 159, 188);
line(x - linelength, y - linelength, x + linelength, y + linelength);
line(x - linelength, y + linelength, x + linelength, y - linelength);
//short crosses that break up the diagonal lines
var linelengthHorizon = 5;
stroke(18, 120, 161);
strokeCap(ROUND);
line(x - linelengthHorizon, y, x + linelengthHorizon, y);
line(x, y - linelengthHorizon, x, y + linelengthHorizon);
}
}
//normal bird layer
for (var y = 0; y < height + 100; y += 100) {
for (var x = 0; x < width + 100; x += 100) {
bird(x, y);
}
}
//offset bird layer
for (var y = 50; y < height + 100; y += 100) {
for (var x = 50; x < width + 100; x += 100) {
bird(x, y);
}
}
}
function bird(x, y) {
push();
translate(x, y);
noStroke();
//bird variables:
var birdHeadS = 20;
var birdHeadX = -25;
var birdHeadY = -33;
var birdBodyW = 40;
var birdBodyH = 30;
var birdBodyX = -35;
var birdBodyY = -25;
var birdDisplacement = 12;
//left bird: beak, head, body
fill(255, 197, 67);
triangle(birdHeadX - birdDisplacement, birdHeadY + 6, birdHeadX - birdDisplacement, birdHeadY - 6, (birdHeadX - birdDisplacement) - 15, birdHeadY);
fill('white');
ellipse(birdHeadX - birdDisplacement, birdHeadY, birdHeadS, birdHeadS);
arc(birdBodyX - birdDisplacement, birdBodyY, birdBodyW, birdBodyH, PI * 7/4, PI * 3/4);
//right bird: beak, head, body
fill(255, 197, 67);
triangle(birdHeadX + birdDisplacement, birdHeadY + 6, birdHeadX + birdDisplacement, birdHeadY - 6, (birdHeadX + birdDisplacement) + 15, birdHeadY - 5);
fill('white');
ellipse(birdHeadX + birdDisplacement, birdHeadY, birdHeadS, birdHeadS);
arc(birdBodyX + birdDisplacement + 20, birdBodyY - 5, birdBodyW, birdBodyW, 0, PI);
//eyes
fill(6, 73, 112);
ellipse(birdHeadX - birdDisplacement - 3, birdHeadY - 2, 3, 3);
ellipse(birdHeadX + birdDisplacement + 3, birdHeadY - 2, 3, 3);
pop();
}
For this project, I wanted to create something that was fairly simple and geometric, but also playful and fun. I started with some sketches, and developed the idea that I wanted to use a grid of some sort, along with pigeons. When I started to create the wall paper, I ended up deviating from my drawing, and I instead tried to explore different elements. For example, I decided to create generic birds, rather than pigeons, and I ended up rotating the grid, moving the birds, and playing with what they looked like.
The project I chose to look at is called Soft Sound, created by EJTECH (Esteban de la Torre and Judit Eszter Kárpáti). Soft Sound combines sound with fabric in order to play with textiles as an audio-emitting surface, and to create multi-sensory interactions. For example, not only can the fabric project sound, but the vibrations caused by the sound interact with the textile, causing it to throb and move. Soft Sound creates “soft” speakers by applying laser or vinyl cut copper and silver coils onto fabric, and running alternating current through the coils.
I found this project interesting and inspiring, as not only does this project turn sound into a more tangible artefact, since you can feel the sound’s vibrations through the fabric, but it’s also done in a very open-ended manner, allowing for the technology to be applied to a variety of different uses, from e-textiles for wearable technology, to more traditional applications at home and everyday.
//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project-04-String Art
function setup() {
createCanvas(400, 300);
}
function draw() {
background(19, 120, 160); //blue background
//Strings
for (var i = 0; i < width; i ++) {
//layer 1, light blue, semi transparent
stroke(207, 239, 255, 75);
line(0, i * 5, i * (mouseX / 5), height);
line(width, height - (i * 5), width - (i * (mouseX / 5)), 0);
line(width, i * 5, width - (i * (mouseX / 5)), height);
line(0, height - (i * 5), i * (mouseX / 5), 0);
//layer 2, dark blue, semi transparent
stroke(9, 73, 112, 75);
line(i * 5, 0, width, i * (mouseY / 5));
line(width - (i * 5), height, 0, height - (i * (mouseY / 5)));
line(i * 5, height, width, height - (i * (mouseY / 5)));
line(width - (i * 5), 0, 0, i * (mouseY / 5));
}
}
For this project, I wanted to make something fairly simple and geometric that you could play with and manipulate with your mouse. While creating the lines, their movement and elegant nature reminded me of lace or weaving, so I decided to go with softer colors.
//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project-03
var oceanY = 480;
var oceanSpeed = 0.05;
var diffocean = 0;
var diffwaves = 1;
var deg = 0;
var brightness = 0;
function setup() {
createCanvas(640, 480);
}
function draw() {
background(220);
noStroke();
fill(34, 110, 148);
rectMode(CORNERS);
//ocean rising and falling
diffocean = mouseY - oceanY;
oceanY = oceanY + oceanSpeed * diffocean;
let conocean = constrain(oceanY, 200, 400)
rect(0, conocean, width, height);
//rain
let rainWeight = constrain(((height - mouseY) / 48), 0, 10);
strokeWeight(rainWeight);
stroke(50, 120, 147, 20);
var cloudsX = width - mouseX;
line(cloudsX + 25, 100, cloudsX + 25, conocean);
line(cloudsX + 50, 100, cloudsX + 50, conocean);
line(cloudsX + 75, 100, cloudsX + 75, conocean);
line(cloudsX + 100, 100, cloudsX + 100, conocean);
line(cloudsX + 125, 100, cloudsX + 125, conocean);
//clouds
noStroke();
rectMode(CORNER);
fill(constrain(mouseY, 50, 255));
rect(cloudsX, 50, 150, 50, 30, 30, 30);
//boat and boat variables
//bmX and bmY are boat middle X and Y
var bmX = 0;
var bmY = 0;
//bw and bh are boat height and width
var bw = 75;
var bh = 40;
//bd is displacement of left and right boat corners above bmY
var bd = 10;
//bblX and bbrX are boat base left and right X
var bblX = bmX - bw / 2;
var bbrX = bmX + bw / 2;
//boat stroke and fill
stroke('black');
strokeWeight(5);
strokeJoin(ROUND);
fill('white');
//rotation of the boat
push();
translate(width / 2, conocean);
rotate(radians(deg), bmX, bmY);
triangle(bblX, bmY, bmX, bmY, bmX, bmY - bh);
triangle(bbrX, bmY, bmX, bmY, bmX, bmY - bh);
triangle(bblX - bw / 2, bmY - bd, bblX, bmY + bh, bmX, bmY);
triangle(bblX, bmY + bh, bbrX, bmY + bh, bmX, bmY);
triangle(bbrX + bw / 2, bmY - bd, bbrX, bmY + bh, bmX, bmY);
pop();
var waves = ((height - mouseY) * 0.05);
deg += (waves / 8) * diffwaves;
if (deg > waves || deg < -waves) {
diffwaves = -diffwaves;
}
//water in front of boat
fill(34, 110, 148);
noStroke();
rect(0, conocean + 25, width, height);
//stormy filter, makes things darker
brightness = height - mouseY;
let conbrightness = constrain(brightness, 0, 100);
fill(12, 52, 68, conbrightness);
rect(0, 0, width, height);
}
For this project, I wanted to play with the idea of a boat at sea that gets caught in a storm. While I ended up simplifying the project as I went along, I still was able to experiment a little with changing position, color, stroke weight, size, and rotation. However, I struggled a lot with getting the rotation to work, and I still wasn’t able to get it to function without occasionally glitching if your mouse goes too low on the canvas.
The project I chose to look at is a part of the Vespers series, a collection of 3D-printed death masks created by Neri Oxman and her Mediated Matter Group at MIT.
The three series within the Vespers collection represents the past, the present, and the future, as the first series explores traditional death masks, and the concept of containing the wearer’s last breath, the second series is the metamorphosis or transition between death masks as an ancient relic and a more contemporary interpretation, and the third series creates an environment that guides and informs gene expression, in the sense that microorganisms inside the mask can produce chemicals that can help their users. In order to meld the masks from all three series together, the team used spatial mapping algorithms to transform the different geometries and colorations from the first series to the second and the second to the third.
I found the third series, “Future, the Biological World” particularly interesting, as not only are the five 3D-printed masks, or “biological urns” beautiful and elegant, but they capture the balance between life and death both visually and physically, through their functions. Using bioactive materials that they then 3D-printed using a Stratasys Objet500 Connex3 multi-material 3D printer, the Mediated Matter Group synthetically engineered microorganisms to produce specific pigments or chemical substances like antibiotics or vitamins. The masks are not only tailored to the physical features, but also to an individuals genetic makeup and their environment, opening up the possibilities for wearable interfaces and skins in the future.