The Holobubble: My Own (Rainbow) “Raumband mit Drei Knoten”

I really loved this week’s assignment, because I thought the computer-generated art in the “Computer Graphics and Art” publication were all so interesting and beautiful. Although it took me a long time to decide which piece I wanted to imitate with Processing, I decided on the Raumband mit Drei Knoten by Dr. Herbert W. Franke (pg. 29) because I loved its strange, twisty, soft shape and thought it would be a good challenge for me (and boy was I right). Directly below on the left is is the original piece by Dr. Franke, and to its right is my attempt at imitating it (which I call the “Holobubble”).

 

Below is a video that more clearly demonstrates how the shape is composed of ellipses:

Recreating this artpiece was incredibly difficult and time-consuming; each curve of the shape was a mystery that I had to discover through trial and error. Despite this (or maybe because of this), I am rather pleased with the result of my attempt, and I believe I get across, albeit imperfectly, the softness and mysteriousness of the original work.

I did not want to stop at only imitating the piece, however; rather, I decided to make a more fun, colorful version that had a little bit of movement. I thus changed the coloring of the work, from white to a multitude of colors that constitute the rainbow. Below I include a video of the rainbow-version; the colors are continuously colored over in rainbow colors, which besides being beautiful adds an element of movement to the piece.

I recreated the artwork by drawing ellipses with various x and y coordinates, as well as various heights and widths. By drawing these consecutive ellipses, I was able to make the appearance of a connected figure. I used sine curves to try to imitate the curves of the figure, and used a frame count to divide the shape into sections.

The most challenging part of creating the figure was determining the right equations according to which I should change the x, y, width, and height parameters. In particular, connecting the various sections of curves proved especially difficult, for I used changes in heights of the ellipses to make the appearances of twists/connections. I include the full code below:

// "HOLOBUBBLE"

float x, y, w, h, c, frame;
int currentColorIndex, colorStep;

int[] rainbowColors = {#f80c12, #ee1100, #ff3311, #ff4422, #ff6644, #ff9933, #feae2d, #ccbb33, #d0c310, #aacc22, #69d025, #22ccaa, #12bdb9, #11aabb, #4444dd, #3311bb, #3b0cbd, #442299};

int[] rainbowColors2 = {#FF0000, #FF7F00, #FFFF00, #00FF00, #0000FF, #4B0082, #9400D3};

void setup() {
 frameRate(60);
 size(600,700);
 background(#333333);
 ellipseMode(CENTER);
 strokeWeight(3);
 noFill();
 repeatedSetup();
}

void repeatedSetup() {
 x = 330 + random(-1,1);
 y = 590 + random(-1,1);
 w = 250;
 h = 40;
 frame = 0;
 currentColorIndex = 0;
 colorStep = 1;
}

void drawWhite() {
 stroke(#FFFFFF);
 ellipse(x,y,w,h);
}

void drawRainbow1() {
 stroke(rainbowColors[int(frame)%rainbowColors.length]); 
 ellipse(x,y,w,h);
}

void drawRainbow2() {
 stroke(rainbowColors[currentColorIndex]); 
 ellipse(x,y,w,h);
 
 if (currentColorIndex == rainbowColors.length-1)
 colorStep = -1;
 
 if (currentColorIndex == 0)
 colorStep = 1;
 
 currentColorIndex += colorStep;
}

void drawRainbow3() {
 stroke(rainbowColors2[currentColorIndex]); 
 ellipse(x,y,w,h);
 
 if (currentColorIndex == rainbowColors2.length-1)
 colorStep = -1;
 
 if (currentColorIndex == 0)
 colorStep = 1;
 
 currentColorIndex += colorStep;
}

void draw() {
 
 drawWhite();
 //drawRainbow1();
 //drawRainbow2();
 //drawRainbow3();
 
 frame += 1;
 
 // PARTS 1 AND 2: LOWER BUBBLE
 if (frame <= 20) {
 x+=5*Math.sin(frame/13);
 y-=6;
 w-=7*Math.sin(frame/26);
 h-=0.25;
 }
 
 else if (frame <= 40) {
 x+=5*Math.sin(frame/13);
 y-=6;
 w-=7*Math.sin(frame/26);
 h-=0.25;
 }
 
 // PARTS 3 AND 4: CONNECTION
 else if (frame <= 60) {
 x+=0.5*Math.sin(frame/13);
 y-=1;
 w-=1.5*Math.sin(frame/26);
 h-=0.25;
 }
 
 else if (frame <= 80) {
 x+=0.5*Math.sin(frame/13);
 y-=1;
 w+=1.5*Math.sin(frame/26);
 h+=0.25;
 }
 
 // PARTS 5 AND 6: UPPER BUBBLE
 else if (frame <= 100) {
 x-=3*Math.sin(frame/13);
 y-=6;
 w-=24*Math.sin((frame-100)/26);
 h+=0.25;
 }
 
 else if (frame <= 120) {
 x-=3*Math.sin(frame/13);
 y-=6;
 w-=12*Math.sin((frame-100)/26);
 h-=0.5;
 }
 
 // PARTS 7 AND 8: TURN
 else if (frame <= 140) {
 x+=7*Math.sin(frame/13);
 y-=1;
 w-=6*Math.sin((frame-100)/26);
 h+=1.5;
 }
 
 else if (frame <= 160) {
 x+=8*Math.sin(frame/13);
 y+=6;
 w+=5*Math.sin((frame-100)/26);
 h-=1;
 }
 
 // PARTS 9 AND 10: UPPER HALF
else if (frame <= 180) {
 x+=Math.sin((frame-80)/13);
 y+=6;
 w-=16*Math.sin((frame-180)/26);
 h-=1;
 }
 
 else if (frame <= 200) {
 x+=2*Math.sin((frame-80)/13);
 y+=6;
 w-=16*Math.sin((frame-180)/26);
 h-=0.5;
 }
 
 
 // PARTS 11 AND 12: LOWER HALF
 else if (frame <= 220) {
 x+=Math.sin((frame-180)/13);
 y+=5;
 w-=4*Math.sin((frame-180)/26);
 h+=0.5;
 }
 
 else if (frame <= 240) {
 x+=Math.sin((frame-200)/13);
 y+=4;
 w+=2*Math.sin((frame-180)/26);
 h-=0.5;
 }
 
 // PARTS 13 AND 14: TWIST
 else if (frame <= 260) {
 x-=4*Math.sin((frame-200)/13);
 y+=3;
 w+=3*Math.sin((frame-180)/26);
 h-=3;
 }
 
 else if (frame <= 280) {
 x-=3*Math.sin((frame-200)/13);
 y-=3;
 w-=24*Math.sin((frame-180)/26);
 h+=6;
 }
 
 else repeatedSetup();
}