Been going slightly nuts trying to simulate a ripple effect visually in Processing. Got this far. Not accurate in a true-to-physics way, but close enough to what I was after. I find Processing great for prototyping visuals, but the graphical objects are a little limited so I may try to reproduce this in Paper.JS next.
Full page version
Here is the code
int x=300; int y=200; int r=200; int[]w; int[]h; int maxamp=200; int col=100; int ageInit=400; int mms=8; int mm=mms; int rw=4; int rb, rp, gb, gp, bb, bp; ArrayList rip; void setup(){ frameRate(24); size(1000,750); rb=50; rp=100; gb=100; gp=100; bb=100; bp=150; w=new int[32]; h=new int[32]; makeWave(); strokeWeight(rw); noFill(); ellipseMode(CENTER); rip=new ArrayList(); Ripple r0=new Ripple(width/2, height/2,0,ageInit); rip.add(r0); } void draw(){ Ripple thisRing; //background (25,75,125); background(rb/10, gb/10, bb/10); for (int i=0; i<h.length; i++){ for (int j=0; j<rip.size();j++){ thisRing=rip.get(j); thisRing.drawRing(i); if(i==0){ if(!thisRing.growRing()) rip.remove(i); } } //fill(col+h[h.length-i-1]); //ellipse(x, y,r-(i*2),(r-(i*2))); } } /* void draw(){ Ripple thisRing; background (col); for (int j=0; j<rip.size();j++){ for (int i=0; i<h.length; i++){ thisRing=rip.get(j); thisRing.drawRing(i); } if(!thisRing.growRing()) rip.remove(i); //fill(col+h[h.length-i-1]); //ellipse(x, y,r-(i*2),(r-(i*2))); } } */ void mouseMoved(){ mm--; if(mm<=0){ mm=mms; Ripple newR=new Ripple(mouseX, mouseY,0, ageInit); rip.add(newR); //println(rip.size()); } } void mousePressed(){ tb=rb; tp=rp; rb=gb; rp=gp; gb=bb; gp=bp; bb=tb; bp=tp; } void makeWave(){ float a=0; int tick=w.length/4; int s=maxamp; float dec=maxamp/(w.length-8); for (int i=0; i<w.length; i++){ w[i]=0; h[i]=(int)((s*100*sin(a))/100); a+=2*PI/tick; s/=1.05; } } class Ripple{ int x; int y; //int force; float rad; int col=100; int r, g, b; int age; Ripple(int x_, int y_, float r_, int age_){ x=x_; y=y_; rad=r_; r=(int)random(rb)+rp; g=(int)random(gb)+gp; b=(int)random(bb)+bp; age=age_; int colMod; } void drawRing(int ring){ //noStroke(); // strokeWeight(2); // noFill(); // pushMatrix(); // ellipseMode(CENTER); // translate(x,y); //ellipse(0,0,r+i, (r+i)/4); //fill(col+h[h.length-ring-1],50); colMod=h[h.length-ring-1]*age/ageInit; stroke(r+colMod, g+colMod, b+colMod,age-50+colMod); //stroke(col+h[h.length-ring-1],age/4); ellipse(x, y,rad-(ring*rw),(rad-(ring*rw))/2); // popMatrix(); } boolean growRing(){ rad+=6; if(((x+rad/2)>width)&&((x+rad/2)<width+4)){ //x=width+(width-x); //Ripple r=new Ripple(width+(width-x), y,rad); Ripple ri=new Ripple(width+(width-x), y,rad, age/2); rip.add(ri); //rip=(Ripple[])append(rip, ri); } if(((x-rad/2)<0)&&((x-rad/2)>-4)){ //x=-x; Ripple ri=new Ripple(-x, y,rad, age/2); rip.add(ri); //rip=(Ripple[])append(rip, ri); } if(((y+rad/2)>height)&&((y+rad/2)<height+2)){ Ripple ri=new Ripple(x,height+(height-y),rad,age/2); rip.add(ri); } if(((y-rad/2)<0)&&((y-rad/2)>-2)){ Ripple ri=new Ripple(x, -y,rad,age/2); rip.add(ri); } age/=1.02; if(age<5) return false; else return true; } }
No comments yet.