import processing.opengl.*; int numThreads = 0; int maxThreads = 1001; int clusterNum = 6; //float colorOffset = 0.0; Helix[] threads = new Helix[maxThreads]; void setup() { colorMode(HSB, 100); size(900, 350, OPENGL); frameRate(45); background(0,0,10); noStroke(); } void draw() { /*int cloudCount = 200; float cloudSize = 60; for(int i = 0; i <= cloudCount; i++) { fill(random(0,100), 100, 100, 1); float fillerSize = random(1,cloudSize); ellipse(random(0,width), random(0,height), fillerSize, fillerSize); }*/ for(int i = 0; i < numThreads; i++) { threads[i].animate(); } if(numThreads == maxThreads) { if(threads[maxThreads-1].disease > 110) { numThreads = 0; } } } class HelixSlice { float x; float y; float nx; float ny; float Scale; int Phase; float pointerX; float pointerY; color triFace; color triBack; HelixSlice(float x, float y, float nx, float ny, float Scale, int Phase, color triFace, color triBack) { this.x = x; this.y = y; this.ny = nx; this.ny = ny; this.Scale = Scale; this.Phase = Phase; this.triFace = triFace; this.triBack = triBack; beginShape(TRIANGLES); switch(Phase) { case 1: pointerX = x; pointerY = y; fill(triFace); vertex(pointerX, pointerY); vertex((pointerX + Scale), (pointerY + (3 * Scale))); vertex((nx + Scale), (ny + (3 * Scale))); pointerX += Scale; pointerY += 6 * Scale; vertex(pointerX, pointerY); vertex((pointerX - Scale), (pointerY + (3 * Scale))); vertex(nx, (ny + (9 * Scale))); pointerX -= 4 * Scale; pointerY += 2 * Scale; fill(triBack); vertex(pointerX, pointerY); vertex((pointerX - Scale), (pointerY - (3 * Scale))); vertex((nx - (4 * Scale)), (ny + (5 * Scale))); pointerX -= Scale; pointerY -= 6 * Scale; vertex(pointerX, pointerY); vertex((pointerX + Scale), (pointerY - (3 * Scale))); vertex((nx - (3 * Scale)), (ny - Scale)); break; case 2: pointerX = x + Scale; pointerY = y + (3 * Scale); fill(triFace); vertex(pointerX, pointerY); vertex((nx + Scale), (ny + (3 * Scale))); vertex((nx + Scale), (ny + (6 * Scale))); pointerX -= Scale; pointerY += 6 * Scale; fill(triBack); vertex(pointerX, pointerY); vertex(nx, (ny + (9 * Scale))); vertex((nx - (3 * Scale)), (ny + (8 * Scale))); pointerX -= 4 * Scale; pointerY -= 4 * Scale; vertex(pointerX, pointerY); vertex((nx - (4 * Scale)), (ny + (5 * Scale))); vertex((nx - (4 * Scale)), (ny + (2 * Scale))); pointerX += Scale; pointerY -= 6 * Scale; fill(triFace); vertex(pointerX, pointerY); vertex(nx, ny); vertex((nx - (3 * Scale)), (ny - Scale)); break; case 3: pointerX = x + Scale; pointerY = y + (3 * Scale); fill(triFace); vertex(pointerX, pointerY); vertex(pointerX, (pointerY + (3 * Scale))); vertex((nx + Scale), (ny + (6 * Scale))); pointerX -= Scale; pointerY += 6 * Scale; fill(triBack); vertex(pointerX, pointerY); vertex((pointerX - (3 * Scale)), (pointerY - Scale)); vertex((nx - (3 * Scale)), (ny + (8 * Scale))); pointerX -= 4 * Scale; pointerY -= 4 * Scale; vertex(pointerX, pointerY); vertex(pointerX, (pointerY - (3 * Scale))); vertex((nx - (4 * Scale)), (ny + (2 * Scale))); pointerX += Scale; pointerY -= 6 * Scale; fill(triFace); vertex(pointerX, pointerY); vertex(x, y); vertex(nx, ny); break; case 4: pointerX = x; pointerY = y; fill(triFace); vertex(pointerX, pointerY); vertex(nx, ny); vertex((nx + Scale), (ny + (3 * Scale))); pointerX += Scale; pointerY += 6 * Scale; vertex(pointerX, pointerY); vertex((nx + Scale), (ny + (6 * Scale))); vertex(nx, (ny + (9 * Scale))); pointerX -= 4 * Scale; pointerY += 2 * Scale; fill(triBack); vertex(pointerX, pointerY); vertex((nx - (3 * Scale)), (ny + (8 * Scale))); vertex((nx - (4 * Scale)), (ny + (5 * Scale))); pointerX -= Scale; pointerY -= 6 * Scale; vertex(pointerX, pointerY); vertex((nx - (4 * Scale)), (ny + (2 * Scale))); vertex((nx - (3 * Scale)), (ny - Scale)); break; default: break; } endShape(); } } class Helix { float pointerX; float pointerY; float slopeX; float slopeY; boolean flip = false; float Scale = random(0.5,1); int Phase = 1; float offsetX = random(1, maxThreads); float offsetY = random(1, maxThreads); float nx; float ny; float age = 0; float disease = 0; float seedHue; Helix(float originX, float originY, float seedHue) { pointerX = originX; pointerY = originY; this.seedHue = seedHue; nx = pointerX; ny = pointerY; } void animate() { if(nx > (width + (20 * Scale)) || nx < -(20 * Scale) || ny > (height + (20 * Scale)) || ny < -(20 * Scale)) { if(flip == true) { flip = false; } else { flip = true; } } else { slopeX = (noise(offsetX) * 2) - 1; slopeY = (noise(offsetY) * 2) - 1; } /* if((nx / mouseX) > .6 && (nx / mouseX) < 1.4 && (ny / mouseY) > .5 && (ny / mouseY) < 1.5) { flip = true; }*/ if(flip) { slopeX *= -1; slopeY *= -1; } offsetX += 0.005; offsetY += 0.005; seedHue = random(age,(age + 0.05)); //if(seedHue > 100) { seedHue = 0; } color faceColor = color(random(seedHue, (seedHue + 1)), (100 - disease), 100, 75); color backColor = color(random(seedHue, (seedHue + 1)), (100 - disease), 100, 70); age += .1; if(age > 80) { disease += random(0,1); } nx += Scale * slopeX; ny -= Scale * slopeY; if(disease < 115) { new HelixSlice(pointerX, pointerY, nx, ny, Scale, Phase, faceColor, backColor); new HelixSlice(pointerX, pointerY, nx, ny, Scale, (Phase + 1), faceColor, backColor); pointerX = nx; pointerY = ny; nx += (Scale * slopeX) * 5; ny -= (Scale * slopeY) * 5; Phase += 2; if(Phase == 5) { Phase = 1; } } } } void mouseDragged() { //colorOffset += 0.01; //float seedHue = noise(colorOffset) * 100; float seedHue = 0; for(int i = 0; i < clusterNum; i++) { if(numThreads < maxThreads) { threads[numThreads] = new Helix(mouseX, mouseY, seedHue); numThreads++; } } } void keyPressed() { numThreads = 0; setup(); }