John Edmark’s series of 3D printed sculptures based off of the golden ratio (phi) reflects the intersection of science, nature, and art. The work is often described as creating an optical illusion, the sculpture’s pieces are rotating, but it appears as if it is in bloom like a flower. This relationship can be attributed to the sculpture mimicking phyllotaxis because of its inclusion of the Fibonacci sequence. The art is the result of the sculpture itself as well as the form in which it is communicated, including strobe lights and shutter speed. This inclusion is interesting because some of the sculptures are actually available for purchase, which I think negates the complete automation of the art as a whole. I do love the simplicity of the execution though. The clean, repetitive lines and white material allow the viewer to focus on the shape and motion of the object, rather than the construction itself.
Month: September 2021
Project 03- Dynamic Drawing
//Catherine Liu
//jianingl@andrew.cmu.edu
//Section D
// bee follows cursor and creates flowers when it gets near stems
var x = 300;
var y = 200;
var dx = 0;
var dy = 0;
var angle = 0;
function setup() {
createCanvas(600, 450);
background(204,255,255);
}
function draw() {
noStroke()
//bee follows mouse
dx = mouseX - x;
dy = mouseY - y;
x = x + 1*dx;
y = y + 1*dy
background(204,255,255);
//sun rotates according to mouse
fill(0,153,0)
push();
fill(255,128,0);
translate(300,450/2);
rotate(radians(abs(mouseX/3)));
ellipse(-200,-70,100,100)
pop();
rect(0,height-40,width,40);
fill(0,255,0); //flower stems
rect(445,370,10,80);
rect(295,370,10,80);
rect(145,370,10,80);
if (dist(mouseX, mouseY, 450, 350) < 50) {
if (dist(mouseX, mouseY, 450, 350) < 25) {
fill(255,153,255); // flower petal is pink
} else {
fill(255,0,0) // flower petal is red
}
ellipse(450, 350, max(mouseX-340,mouseY-340), max(mouseX-340,mouseY-340));
fill(255,255,0); // flower center
ellipse(450, 350, max(mouseX-380,mouseY-380), max(mouseX-380,mouseY-380)); //make right flower bigger
fill(255,0,0); // flower petal
ellipse(300, 350, 250-(max(mouseX-250,mouseY-250)), 250-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(300, 350, 180-(max(mouseX-290,mouseY-290)), 180-(max(mouseX-290,mouseY-290))); //make middle flower smaller
fill(255,0,0); // flower petal
ellipse(150, 350, 250-(max(mouseX-250,mouseY-250)), 250-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(150, 350, 180-(max(mouseX-290,mouseY-290)), 180-(max(mouseX-290,mouseY-290))); //make left flower smaller
} else if (dist(mouseX, mouseY, 300, 350) < 50) {
if (dist(mouseX, mouseY, 300, 350) < 25) {
fill(255,128,0); // flower petal is orange
} else {
fill(255,0,0) // flower petal is red
}
ellipse(300, 350, max(mouseX-250,mouseY-250), max(mouseX-250,mouseY-250));
fill(255,255,0); // flower center
ellipse(300, 350, max(mouseX-290,mouseY-290), max(mouseX-290,mouseY-290)); // make middle flower bigger
fill(255,0,0); // flower petal
ellipse(450, 350, 170-(max(mouseX-250,mouseY-250)), 170-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(450, 350, 100-(max(mouseX-290,mouseY-290)), 100-(max(mouseX-290,mouseY-290))); //make right flower smaller
fill(255,0,0); // flower petal
ellipse(150, 350, 170-(max(mouseX-250,mouseY-250)), 170-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(150, 350, 100-(max(mouseX-290,mouseY-290)), 100-(max(mouseX-290,mouseY-290))); //make left flower smaller
} else if (dist(mouseX, mouseY, 150, 350) < 50) {
if (dist(mouseX, mouseY, 150, 350) < 25) {
fill(178,102,255); // flower petal is purple
} else {
fill(255,0,0) // flower petal is red
}
ellipse(150, 350, max(mouseX-250,mouseY-250), max(mouseX-250,mouseY-250));
fill(255,255,0); // flower center
ellipse(150, 350, max(mouseX-300,mouseY-300), max(mouseX-300,mouseY-300)); // make left flower bigger
fill(255,0,0); // flower petal
ellipse(450, 350, 170-(max(mouseX-250,mouseY-250)), 170-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(450, 350, 100-(max(mouseX-290,mouseY-290)), 100-(max(mouseX-290,mouseY-290))); //make right flower smaller
fill(255,0,0); // flower petal
ellipse(300, 350, 170-(max(mouseX-250,mouseY-250)), 170-(max(mouseX-250,mouseY-250)));
fill(255,255,0); // flower center
ellipse(300, 350, 100-(max(mouseX-290,mouseY-290)), 100-(max(mouseX-290,mouseY-290)));//make middle flower smaller
}
fill(255)
ellipse(x-20,y-30,20,40); //bee wing
ellipse(x-10,y-30,20,40); //bee wing
fill(255,174,66);
ellipse(x-15,y,50,25); //bee body
fill(0)
ellipse(x,y,5,5); // bee eye
rect(x-55,y-5,20,10); // bee stinger
}
It took a while coming up with an idea but in the end I decided to do something fun and interactive like a game. When you move the bee close to the flower stems, a flower “blooms” while the others get smaller. I spent a long time making sure the sizes and numbers were correct but I’m happy with the end result.

Generative Art
I really like this piece by Sawako & Panagiotis. I found them from the Scripted By Purpose page. https://scriptedbypurpose.wordpress.com/participants/akt/
They are computational design researchers, who tie programming and architecture to generate infrastructure. I picked this image in particular because it looks like something I could try to recreate in p5.js if I spent a good amount of time working on it.
The piece seems like it consists of one string of a manipulated shape being repeated over and over again, similarly to if you were to draw a series of ellipses or rectangles without redrawing the background. I’m sure a lot more went into rendering this image than just that, but those are my initial thoughts. I’m curious about what sort of functions would create the manipulation of the shape? I am not a numbers person, so navigating this type of computational art is a challenge.
Project-03-Dynamic-Drawing
//Nami Numoto
//Section A
function setup() {
createCanvas(600, 450);
background(0);
}
function draw() {
background(0); // initialize background
fill(255, 255, 0); // yellow
var m = max(min(mouseX, 600), 0); //restrict x to the canvas (600)
var size = m * 350.0 / 400.0; // manipulate sizes of the circles
ellipse(mouseX, mouseY, size, size); //yellow dot that follows mouse
fill(0, 0, 255); // blue
size = 400 - size;
ellipse((width - mouseX), (height - mouseY), size, size); //blue dot that follows mouse inversely sort of
}
// everything the mouse 'draws' or hovers (yellow dot) should be mirrored about the y axis by the blue dot
// make them change size contrarily
I wanted to go off of the example while keeping it original. I’ve always been intrigued by mirror images and reflections, so I decided to reflect the user’s mouse trails about the y-axis and practice using contrary sizing.
I’ve noticed that the blue ellipse is not showing up, although it works in my index.html file… trying to work that out still
LookingOutwards-03
I really appreciate the depth and negative space of this piece, and it reminds me of the example work from Prof. Levin’s article, PolyMorph.
Instead of a simply amorphous shape, however, this artist decided to arrange a face using the 3D interconnected units.
My favorite aspect is the use of spaces – despite there being so many small cavities, little distracts the viewer from the facial features.
While I’m not entirely sure the face is human and the uncertainty feels somewhat unsettling, there is also a dichotomous fullness and liveliness to the piece that brings me a sense of wonder, which is what I believe the artist was going for.
There’s a certain mix between realism and abstraction that makes this piece stand out.
Project-03: Dynamic Drawing, “groovy”
var thickness = 20; // <-- value for weight of image parts (element: size)
var r = 0; // <-- value for rotation angle (element: angle)
var p = -40; // <-- value for disco ball placement (element: position)
var b = 0; // <-- value for brightness (element: color)
function setup() {
createCanvas(600, 450);
rectMode(CENTER);
}
function draw() {
background(0);
stroke(0);
fill(100);
rect(width/4, p-75, 5, 200);
rect(3*width/4, p-75, 5, 200);
if (int(b)==b) { // color variation for disco ball
fill(162+b);
} else {
fill(162);
}
//disco ball:
ellipse(width/4, p, 80, 80);
line(width/4, p-40, width/4, p+40);
line(width/4-5, p-40, width/4-5, p+40);
line(width/4-10, p-40, width/4-10, p+40);
line(width/4-15, p-40, width/4-15, p+40);
line(width/4-20, p-40, width/4-20, p+40);
line(width/4-25, p-40, width/4-25, p+40);
line(width/4-30, p-40, width/4-30, p+40);
line(width/4-35, p-40, width/4-35, p+40);
line(width/4-40, p-40, width/4-40, p+40);
line(width/4+5, p-40, width/4+5, p+40);
line(width/4+10, p-40, width/4+10, p+40);
line(width/4+15, p-40, width/4+15, p+40);
line(width/4+20, p-40, width/4+20, p+40);
line(width/4+25, p-40, width/4+25, p+40);
line(width/4+30, p-40, width/4+30, p+40);
line(width/4+35, p-40, width/4+35, p+40);
line(width/4+40, p-40, width/4+40, p+40);
line(width/4-40, p, width/4+40, p);
line(width/4-40, p-5, width/4+40, p-5);
line(width/4-40, p-10, width/4+40, p-10);
line(width/4-40, p-15, width/4+40, p-15);
line(width/4-40, p-20, width/4+40, p-20);
line(width/4-40, p-25, width/4+40, p-25);
line(width/4-40, p-30, width/4+40, p-30);
line(width/4-40, p-35, width/4+40, p-35);
line(width/4-40, p-40, width/4+40, p-40);
line(width/4-40, p+5, width/4+40, p+5);
line(width/4-40, p+10, width/4+40, p+10);
line(width/4-40, p+15, width/4+40, p+15);
line(width/4-40, p+20, width/4+40, p+20);
line(width/4-40, p+25, width/4+40, p+25);
line(width/4-40, p+30, width/4+40, p+30);
line(width/4-40, p+35, width/4+40, p+35);
line(width/4-40, p+40, width/4+40, p+40);
//second disco ball:
ellipse(3*width/4, p, 80, 80);
line(3*width/4, p-40, 3*width/4, p+40);
line(3*width/4-5, p-40, 3*width/4-5, p+40);
line(3*width/4-10, p-40, 3*width/4-10, p+40);
line(3*width/4-15, p-40, 3*width/4-15, p+40);
line(3*width/4-20, p-40, 3*width/4-20, p+40);
line(3*width/4-25, p-40, 3*width/4-25, p+40);
line(3*width/4-30, p-40, 3*width/4-30, p+40);
line(3*width/4-35, p-40, 3*width/4-35, p+40);
line(3*width/4-40, p-40, 3*width/4-40, p+40);
line(3*width/4+5, p-40, 3*width/4+5, p+40);
line(3*width/4+10, p-40, 3*width/4+10, p+40);
line(3*width/4+15, p-40, 3*width/4+15, p+40);
line(3*width/4+20, p-40, 3*width/4+20, p+40);
line(3*width/4+25, p-40, 3*width/4+25, p+40);
line(3*width/4+30, p-40, 3*width/4+30, p+40);
line(3*width/4+35, p-40, 3*width/4+35, p+40);
line(3*width/4+40, p-40, 3*width/4+40, p+40);
line(3*width/4-40, p, 3*width/4+40, p);
line(3*width/4-40, p-5, 3*width/4+40, p-5);
line(3*width/4-40, p-10, 3*width/4+40, p-10);
line(3*width/4-40, p-15, 3*width/4+40, p-15);
line(3*width/4-40, p-20, 3*width/4+40, p-20);
line(3*width/4-40, p-25, 3*width/4+40, p-25);
line(3*width/4-40, p-30, 3*width/4+40, p-30);
line(3*width/4-40, p-35, 3*width/4+40, p-35);
line(3*width/4-40, p-40, 3*width/4+40, p-40);
line(3*width/4-40, p+5, 3*width/4+40, p+5);
line(3*width/4-40, p+10, 3*width/4+40, p+10);
line(3*width/4-40, p+15, 3*width/4+40, p+15);
line(3*width/4-40, p+20, 3*width/4+40, p+20);
line(3*width/4-40, p+25, 3*width/4+40, p+25);
line(3*width/4-40, p+30, 3*width/4+40, p+30);
line(3*width/4-40, p+35, 3*width/4+40, p+35);
line(3*width/4-40, p+40, 3*width/4+40, p+40);
translate(width/2, height/3);
rotate(radians(-r));
//BODY of image:
noStroke();
fill(255);
triangle(-7, -thickness/2+1, 7, -thickness/2+1, 0, -50); //neck
ellipse(0, -60, 60+thickness/2, 60+thickness/2); // head
fill(200+b, 100-b, 50+b); // variable used for color change
rect(0, 0, width/4, thickness); // shoulders
if (constrain(mouseX, width/10, 2*width/10) == mouseX || //dancing motion! for body
constrain(mouseX, 3*width/10, 4*width/10) == mouseX ||
constrain(mouseX, 5*width/10, 6*width/10) == mouseX ||
constrain(mouseX, 7*width/10, 8*width/10) == mouseX ||
constrain(mouseX, 9*width/10, width) == mouseX) {
quad(-thickness,0, thickness,0, width/8+5, height/3, -width/8+5, height/3); // body
} else {
quad(-thickness,0, thickness,0, width/8-5, height/3, -width/8-5, height/3); // body
}
fill(255);
quad(-width/8+1,thickness/2, -width/8+1,-thickness/2, -width/16,-thickness+70, -width/16,+70); // left arm
if (mouseX < width/2 & mouseX > width/4 || mouseX > 3*width/4) {
quad(width/8-1,thickness/2, width/8-1,-thickness/2, 0,-thickness+75, 0,75); //right arm
} else {
quad(width/8-1,thickness/2, width/8-1,-thickness/2, width/4-1,-thickness-50, width/4-1,-50); //disco baby!
}
quad(-10,height/3-1, -10-thickness,height/3-1, -20-thickness,height/3+50, -20,height/3+50); //left leg
quad(10,height/3-1, 10+thickness,height/3-1, 20+thickness,height/3+50, 20,height/3+50); // right leg
fill(100);
triangle(-20-thickness,height/3+50, -20,height/3+50, -30-thickness, height/3+65); //left shoe
triangle(20+thickness,height/3+50, 20,height/3+50, 30+thickness, height/3+65); // right shoe
noFill();
stroke(0);
arc(0, -60, 30+thickness/2, 30+thickness/2, 0, PI); // smile
arc(-10, -70, 15, 15, PI, 0); //eye
arc(10, -70, 15, 15, PI, 0); //eye
//rotation limits:
if ((mouseX - width/2)/10 <= -20) {
r = -20;
} else if ((mouseX - width/2)/10 >= 20) {
r = 20;
} else {
r = (mouseX - width/2)/10;
}
if (mouseY/10 <= 10) {
thickness = 10;
} else if (mouseY/10 >= 35) {
thickness = 35;
} else {
thickness = (mouseY)/10;
}
//color change:
b = r*5;
//disco drop:
if (-mouseY + 300 <= -40) {
p = -40;
} else if (-mouseY + 300 >= 100) {
p = 100;
} else {
p = - mouseY + 300;
}
}
When I read the requirements for this assignment, I kept thinking about watching the shapes ‘dance’ around on the screen, which inspired the image I created.
Project 3: Dynamic Drawing
function setup() {
createCanvas(600, 450);
}
function draw() {
var positionY = constrain(mouseY, 80, 400); //relative Y position for everything that is constrained so the sun doesnt shoot off into the sky etc
background(139,214,241);
fill(21,8,29, mouseY - 80); //transitions background to night sky by decreasing transparency with mouseY position
rect(0,0,600,300);
var rainbowAlpha = map(constrain(mouseY,80,400), 80, 250, 255, 0); //variable to control transparency of the rainbow as it goes down
noStroke();
fill(255,0,0,rainbowAlpha); //the rainbow: red
ellipse(300, positionY + 100, 700, 200);
fill(254,98,48,rainbowAlpha); //orange
ellipse(300, positionY + 120, 700, 200);
fill(255,246,2,rainbowAlpha); //yellow
ellipse(300, positionY + 140, 700, 200);
fill(1,179,2,rainbowAlpha); //green
ellipse(300, positionY + 160, 700, 200);
fill(4,1,119,rainbowAlpha); //blue
ellipse(300, positionY + 180, 700, 200);
fill(35,3,114,rainbowAlpha); //violet
ellipse(300, positionY + 200, 700, 200,);
fill(139,214,241); //"clear" ellipse that is the same color as the day background
ellipse(300, positionY + 220, 700, 200,);
fill(21,8,29, mouseY - 80); //"clear" ellipse that tranistions to night sky same why the regular background does
ellipse(300, positionY + 220, 700, 200);
fill(255,246,2); //sun
circle(150, positionY - 50, 50);
fill(241,222,150); //moon
circle(390, positionY - 325, 30);
fill(233,233,255,mouseY - 250); //stars
circle(40,96,10);
circle(250,15,10);
circle(330,62,10);
circle(470,340,10);
circle(580,70,10);
circle(346,54,10);
circle(200,30,10);
circle(475,120,10);
circle(175,60,10);
circle(275,115,10);
circle(430,50,10);
circle(20,20,10);
circle(100,40,10);
circle(270,50,10);
circle(80,130,10);
circle(500,25,10);
circle(400,100,10);
circle(150,85,10);
circle(500,55,10);
var positionX = constrain(mouseX,35,565);
fill(141,196,39); //green "field"
rect(0,300,600, 150);
var oppositeX = map(positionX, 0, 600, 600, 0);
fill(103,62,16); //left dog
ellipse(positionX, 350,30,15); //body
circle(positionX + 15, 345,15); //head
ellipse(positionX-10,355, 5,8); //leg
ellipse(positionX + 10, 355, 5, 8); //leg
ellipse(positionX-15,350,15,5); //tail
triangle(positionX+9,340,positionX+12,335,positionX+16,340); //ear
triangle(positionX+14,340,positionX+17,335,positionX+20,340); //ear
fill(0);
circle(positionX+16,343,2); //eyes
circle(positionX+19,343,2);
fill(103,62,16); //right dog
ellipse(oppositeX, 390,30,15); //body
circle(oppositeX - 15, 385,15); //head
ellipse(oppositeX + 10,395, 5,8); //leg
ellipse(oppositeX - 10, 395, 5, 8); //leg
ellipse(oppositeX + 15,390,15,5); //tail
triangle(oppositeX - 9,380,oppositeX - 12,375,oppositeX - 16,380); //ear
triangle(oppositeX - 14,380,oppositeX - 17,375,oppositeX - 20,380); //ear
fill(0);
circle(oppositeX - 16,383,2); //eyes
circle(oppositeX - 19,383,2);
}
I had difficulty with this project. I had a hard time coming up with something to draw. Once I had an idea I really enjoyed coming up with ways as to how I could incorporate dynamic elements into it. One thing, in particular, I am proud of is figuring out that the map function can work backwards, with the higher value being the start point and the lower value being the stop point, which allows you to invert the value of a variable in a sense.
LO-03: Computational Fabrication
The project I chose for this blog is a KUKA robotic arm parametric cuboid grid fabrication. Posted to the journal for the Institute for advanced architecture of Catalonia, this project utilizes KUKA robotic arm technology to build a wooden grid with variable density out of wooden battens and pins. Modules for the grid can be assembled (cutting, drilling, positioning) entirely by the robot arm. Modules with varying programmed densities can be connected together to complete complex structures. I like this project because of the simplistic method it uses to create structures. By programming the KUKA arm to your own personal parameters, an infinite number of structures can be built and used for the construction of art, architecture, models, etc. As shown in the attached image, the robot arm is able to build grids with complex densities while using a singular building strategy by altering the lengths of the battens and the space between connections.
ROBOTIC FABRICATION – CUBOID GRID
INSTITUTE FOR ADVANCED ARCHITECTURE OF CATALONIA, BARCELONA
MARCH 29, 2016

“Speculating on the final form shows how density can be controlled throughout the structure.”
Looking Outwards 3
I looked at Torolf Saurmann’s Moebius Ring. I chose this piece because I find its intricacy really beautiful. The strange spiral the ring inverts itself on is facilitating to look at and the mesh design it has increases that enjoyment. Because of the mesh design, the ring is somewhat see through. This further complicates of the spiral inverts itself and requires the viewer to focus to understand it. I find it really fun and enjoy the design. The algorithm that generated this work was likely very versatile and I think that comes from the mesh design. Not only does the mesh save material, it also puts the entire project into component parts that were likely much easier to code into larger designs. The Ring is also able to stand up on its own and I wonder if that is a coincidence or something the algorithm makes sure can happen. Saurmann as an artist really likes round and circular shapes, which one can see in his other work. In this piece he doubles down on that by basing his design on a Mobius Strip, a circle that inverts and doubles back on itself. This piece does that multiple times, to the point where its hard to tell where one inversion stops another the next begins.
Torolf Saurmann

LO 03: Computational Fabrication
This is a flower kiosk designed by the British firm Archio. The ripples in the timber facade of this kiosk are demonstrative of the shapes of flower petals when viewed under a microscopic lens. Archio constructed the kiosk by integrating both digital and handmade techniques. The nano details of the petals were scanned through the electron scanning technique. Computer programming would help the transformation of the scanned image into the fabrication of the timber ripples. This project was eye-catching for its visual attractiveness and practicality. The compact and simplistic design of the kiosk seemed to successfully match its usage as a flower shop. Realizing the process to the final design, the gentle curves resonate better with the concept of flowers. The creative process of capturing the interesting form of flower petals to wooden ridges aided by computer programs highlights how the computer can be used to generate both practical and creative outcomes.