// blur adapted from super fast blur by Mario Klingemann (http://incubator.quasimondo.com/processing/superfastblur.pde) int NUM_PARTICLES = 64; int NUM_ATTRACTORS = 3; int BLUR_RADIUS = 12; int SPRITE_SIZE = 20; int currentAttractor = -1; Particle[] particle; Attractor[] attractor; class Particle { float damp, accel; float x,y,vx,vy,px,py; Particle() { damp = 0.99; accel = 8; x = px = random(width); y = py = random(height); vx = random(-accel/2,accel/2); vy = random(-accel/2,accel/2); } void step() { forces(); move(); } void forces() { 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; } } } void move() { px = x; py = y; x += vx; y += vy; vx *= damp; vy *= damp; } } class Attractor { float x,y; int currentPoint = 0; Attractor() { x = random(width); y = random(height); } void step() { x += (mouseX-x)/5.0; y += (mouseY-y)/5.0; } } void setup() { size(360,360); background(0); stroke(255); 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(); } part = new BImage(SPRITE_SIZE,SPRITE_SIZE); float md = 0.5*sqrt(sq(part.width/2)+sq(part.height/2)); for (int x = 0; x < part.width; x++) { for (int y = 0; y < part.height; y++) { float d = sqrt(sq(x-part.width/2)+sq(y-part.height/2)); part.set(x,y,color(255-255*d/md,64-64*d/md,160-160*d/md)); } } part.alpha(part); imageMode(CENTER_DIAMETER); ellipseMode(CENTER_DIAMETER); } BImage part; void loop() { if (mousePressed) { if (currentAttractor >= 0) { attractor[currentAttractor].step(); } else { for (int i = 0; i < attractor.length; i++) { if ( sq(mouseX-attractor[i].x) + sq(mouseY-attractor[i].y) < 250) { currentAttractor = i; break; } } } background(0); stroke(255,128,0); for (int j = 0; j < particle.length; j++) { particle[j].step(); ellipse(particle[j].x, particle[j].y, 5, 5); } noStroke(); fill(255,128); for (int i = 0; i < attractor.length; i++) { ellipse(attractor[i].x, attractor[i].y, 25, 25); } } else { cursor(ARROW); for (int i = 0; i < attractor.length; i++) { if ( sq(mouseX-attractor[i].x) + sq(mouseY-attractor[i].y) < 250) { cursor(HAND); break; } } currentAttractor = -1; fastblur(g,BLUR_RADIUS); for (int j = 0; j < particle.length; j++) { particle[j].step(); blend(part,0,0,part.width,part.height,(int)particle[j].x,(int)particle[j].y,(int)particle[j].x+part.width,(int)particle[j].y+part.height,ADD); } } } void fastblur(BImage img,int radius){ if (radius<1){ return; } int w=img.width; int h=img.height; int wm=w-1; int hm=h-1; int wh=w*h; int div=radius+radius+1; int r[]=new int[wh]; int g[]=new int[wh]; int b[]=new int[wh]; int rsum,gsum,bsum,x,y,i,p,p1,p2,yp,yi,yw; int vmin[] = new int[max(w,h)]; int vmax[] = new int[max(w,h)]; int[] pix=img.pixels; int dv[]=new int[256*div]; for (i=0;i<256*div;i++){ dv[i]=(i/div); } yw=yi=0; for (y=0;y>16; gsum+=(p & 0x00ff00)>>8; bsum+= p & 0x0000ff; } for (x=0;x>16; gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff); yi++; } yw+=w; } for (x=0;x