// string_0 (2005. 2. 14.) // by SeungJoon Choi // erucipe@hanmail.net // // http://processing.org float[] clearZ; Column[] columns; int n_col; void setup() { size(400, 300); Sonia.start(this); LiveInput.start(64); LiveInput.useEnvelope(true,50); LiveInput.useEqualizer(true); clearZ = new float[width*height]; System.arraycopy(g.zbuffer, 0, clearZ, 0, clearZ.length); rectMode(CENTER_RADIUS); ellipseMode(CENTER_RADIUS); background(0); //lights(); noStroke(); n_col = 64; columns = new Column[n_col]; for(int i = 0; i < n_col; i++) { columns[i] = new Column(); columns[i].Setup((1-random(2))*100, (1-random(2))*100, 5, 10 + (1-random(2))* 10, 3 + (int)random(4)); } } public void stop() { Sonia.stop(); super.stop(); } float rot = 0; void loop() { background(255); System.arraycopy(clearZ, 0, g.zbuffer, 0, clearZ.length); rot += 0.001; float r = 250 + 50*sin(rot); push(); beginCamera(); perspective(60, (float)width / (float)height, 10, 300); //lookat(200 - mouseX, 200, 100, 0, -200, 40, 0, 1, 0); lookat(r * cos(rot), r * sin(rot), 100 + abs(200*cos(rot*2)), 0, 0, 40, 0, 0, -1); endCamera(); pop(); drawPlane(); for(int i = 0; i < n_col; i++) { Column col = columns[i]; col.Update(30); col.Draw(); } LiveInput.getSpectrum(); for ( int i = 0; i < LiveInput.spectrum.length; i++) { columns[i].maxh = LiveInput.spectrum[i]/10; } //blur(g); } void drawPlane() { fill(255, 255, 0, 64); push(); translate(0, 0, 0); /* beginShape(QUADS); vertex(-100, -100, 4); vertex(100, -100, 4); vertex(100, 100, 4); vertex(-100, 100, 4); endShape(); */ ellipse(0, 0, 150, 150); pop(); } class Column { Column() { cR = 64 + (int)random(191); cG = 64 + (int)random(191); cB = 64 + (int)random(191); maxh = 10 + random(90); angle = random(1)*TWO_PI; rt = 1 + (1-random(2))*0.25; twist = 0; n_seg = 1 + (int)random(5); tx = new float[n_seg]; ty = new float[n_seg]; for(int i = 0; i < n_seg; i++) { tx[i] = (1-random(2))*3; ty[i] = (1-random(2))*3; } vx = 0; vy = 0; dt = 0.1; } void Setup(float _x, float _y, float _h, float _radius, int _n) { x = _x; y = _y; h = _h; radius = _radius; n = _n; } void antifield() { for(int i = 0; i < n_col; i++) { Column col = columns[i]; if(this != col) { float dx = x - col.x; float dy = y - col.y; float d = sqrt(dx*dx+dy*dy); float R = radius + col.radius + 5; if(d > 0 && d < R) { float k = R - d; float ux = dx / d; float uy = dy / d; x += k*ux*0.5; y += k*uy*0.5; col.x += -k*ux*0.5; col.y += -k*uy*0.5; } } } } void Update(float _h) { float dx = 0 - x; float dy = 0 - y; float d = sqrt(dx*dx + dy*dy); if(d > 0) { vx += dx/d*0.5; vy += dy/d*0.5; } x += vx*dt; y += vy*dt; vx *= 0.95 + 0.024*(d / 150); vy *= 0.95 + 0.024*(d / 150); if(d > 150) { if(vx*x > 0 && vy*y > 0) { vx *= 0.5; vy *= 0.5; } } antifield(); if(h < maxh) { h *= 1.1; twist += PI*0.1*(1-random(2)); vx = (1-random(2))*50; vy = (1-random(2))*50; } else { h *= 0.999; twist *=0.99; } for(int i = 0; i < n_seg; i++) { d = sqrt(tx[i]*tx[i]+ty[i]*ty[i]); if(d > 0) { tx[i] = d*cos(millis() / d / 100); ty[i] = d*sin(millis() / d / 100); } } } void Draw() { fill(cR, cG, cB); //stroke(cR, cG, cB, 127); stroke(0, 0, 0, 64); push(); translate(x, y, 0); float r1 = radius; float r2 = r1*rt; float theta1 = 0; float theta2 = theta1+twist; int s = 1; float a = (float)h / (float)n_seg; float h1 = 0; float h2 = a; float tx1 = 0; float tx2 = 0; float ty1 = 0; float ty2 = 0; beginShape(QUAD_STRIP); for(int j = 0; j < n_seg; j++) { tx2 = tx[j]; ty2 = ty[j]; float hh = a*(j+1); for(int i = 0; i < n + 1; i++) { float theta = (float)i / (float)n * TWO_PI + angle; if(s > 0) { vertex(r1*cos(theta+theta1) + tx1, r1*sin(theta+theta1) + ty1, h1); vertex(r2*cos(theta+theta2) + tx2, r2*sin(theta+theta2) + ty2, h2); } else { vertex(r2*cos(theta+theta2) + tx2, r2*sin(theta+theta2) + ty2, h2); vertex(r1*cos(theta+theta1) + tx1, r1*sin(theta+theta1) + ty1, h1); } s *= -1; } h1 = h2; h2 += a; r1 = r2; r2 *= 0.9; theta1 = theta2; theta2 += twist; tx1 = tx2; ty1 = ty2; } endShape(); beginShape(TRIANGLE_STRIP); for(int i = 0; i < n+1; i++) { float theta = (float)i / (float)n * TWO_PI + angle; vertex(0, 0, h1+5); vertex(r1*cos(theta+theta1)+tx1, r1*sin(theta+theta1)+ty1, h1); } endShape(); pop(); } float x, y, vx, vy, dt, h, radius, maxh, angle; int n, n_seg; float[] tx; float[] ty; int cR, cG, cB; float twist, rt; } int Red(int c) { return (c & 0xff0000) >> 16; } int Green(int c) { return (c & 0x00ff00) >> 8; } int Blue(int c) { return c & 0x0000ff; } void blur(BGraphics target) { //float divider = 4.99 + random(0.5); //float divider = 5.01; float divider = 5 + (1-random(2))*0.1; int index,left,right,top,bottom; int sumr, sumg, sumb; for(int j=0;j0) left=-1; else left=width-1; if(j==(width-1)) right=-width+1; else right=1; if(i>0) top=-width; else top=(height-1)*width; if(i==(height-1)) bottom=-(height-1)*width; else bottom=width; // Calculate the sum of n neighbors sumr=Red(target.pixels[left+index]); // left middle sumg=Green(target.pixels[left+index]); sumb=Blue(target.pixels[left+index]); sumr+=Red(target.pixels[right+index]); // right middle sumg+=Green(target.pixels[right+index]); sumb+=Blue(target.pixels[right+index]); sumr+=Red(target.pixels[index]); // middle middle sumg+=Green(target.pixels[index]); sumb+=Blue(target.pixels[index]); sumr+=Red(target.pixels[index+top]); // middle top sumg+=Green(target.pixels[index+top]); sumb+=Blue(target.pixels[index+top]); sumr+=Red(target.pixels[index+bottom]); // middle bottom sumg+=Green(target.pixels[index+bottom]); sumb+=Blue(target.pixels[index+bottom]); sumr=(int)((float)sumr/divider); sumg=(int)((float)sumg/divider); sumb=(int)((float)sumb/divider); target.pixels[index]=(sumr<<16)+(sumg<<8)+sumb; } } }