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(); }