int ALPH = 0x10000000; int NUM_PARTICLES = 8192; int NUM_ATTRACTORS = 10; float damp = 0.99999; float accel = 0.2; int[] pixels2; color[] colours = { ALPH | 0x00A3D39C, ALPH | 0x0086AD80, ALPH | 0x00698764, ALPH | 0x00C9D49D, ALPH | 0x00A4AD80, ALPH | 0x00808764, ALPH | 0x002B2B2B, ALPH | 0x00D4D4D4, ALPH | 0x00000000 }; Particle[] particle; Attractor[] attractor; class Attractor { float x,y; Attractor() { x = random(width); y = 0.95*height; } } class Particle { float x,y,vx,vy,px,py; Particle() { x = px = random(width); y = py = random(height); // vx = random(1) > 0.5 ? random(-15,-12) : random(12,15); // vy = random(1) > 0.5 ? random(-15,-12) : random(12,15); vx = random(-accel/2,accel/2); vy = random(-accel/2,accel/2); } void step() { px = x; py = y; for (int i = 0; i < attractor.length; i++) { float d2 = sq(attractor[i].x-x) + sq(attractor[i].y-y); if (d2 > 0.1) { vx += accel * (attractor[i].x-x) / d2; vy += accel * (attractor[i].y-y) / d2; } } x += vx; y += vy; vx *= damp; vy *= damp; } } void setup() { size(256,256); background(0); noFill(); attractor = new Attractor[NUM_ATTRACTORS]; for (int i = 0; i < attractor.length; i++) { attractor[i] = new Attractor(); } particle = new Particle[NUM_PARTICLES]; for (int i = 0; i < particle.length; i++) { particle[i] = new Particle(); particle[i].y = attractor[i%attractor.length].y - random(20); } pixels2 = new int[pixels.length]; // g.depthTest = false; // zcl = new float[pixels.length]; // System.arraycopy(g.zbuffer,0,zcl,0,pixels.length); } float[] zcl; void loop() { // System.arraycopy(zcl,0,g.zbuffer,0,pixels.length); if (keyPressed) { background(0); for (int j = 0; j < particle.length; j++) { particle[j].step(); stroke(255,128); line(particle[j].x,particle[j].y,particle[j].px,particle[j].py); } } else { for (int j = 0; j < particle.length; j++) { particle[j].step(); stroke(colours[j%colours.length]); line(particle[j].x,particle[j].y,particle[j].px,particle[j].py); } // blur(); dissipate(); } } void mousePressed() { for (int i = 0; i < attractor.length; i++) { attractor[i] = new Attractor(); } } void blur() { System.arraycopy(pixels,0,pixels2,0,pixels.length); int red,green,blue; int offset[] = {-width-1, -width+1, width-1, width+1 }; for ( int i = 0; i < pixels.length; i++ ){ red=green=blue=0; for (int j = 0; j < offset.length; j++) { red += (pixels2[min(max(0,i+offset[j]),pixels.length-1)] & 0xff0000); green += (pixels2[min(max(0,i+offset[j]),pixels.length-1)] & 0x00ff00); blue += (pixels2[min(max(0,i+offset[j]),pixels.length-1)] & 0x0000ff); } red >>= 18; green >>= 10; blue >>= 2; pixels[i] = ( ( red << 16 ) | ( green << 8 ) | blue ); } } void dissipate() { System.arraycopy(pixels,0,pixels2,0,pixels.length); int[] kernel = { 0, 0, 0, 0, 1, 0, 10, 10, 10 }; int[] offset = { -width-1, -width, -width+1, -1, 0, 1, width-1, width, width+1 }; int r,g,b; int t = 0; for (int j = 0; j < offset.length; j++) { t += kernel[j]; } t = max(t,1); for (int i = width+1; i < pixels.length-width-1; i++) { if (i % width == 0 || i % width == width-1) { i++; } r = g = b = 0; for (int j = 0; j < offset.length; j++) { int pix = i + offset[j]; r += kernel[j] * ((pixels2[pix] & 0xff0000) >> 16); g += kernel[j] * ((pixels2[pix] & 0x00ff00) >> 8); b += kernel[j] * ( pixels2[pix] & 0x0000ff); } r /= t; g /= t; b /= t; pixels[i] = r << 16 | g << 8 | b; } }