float amplitude = 20.0; float wavelength = 10.0; float wavespeed = 1.0; int x = 200; int y = 200; QuadGrid grid; PImage map; void setup(){ size(400,400,P3D); map = loadImage("onions.jpg"); grid = new QuadGrid (50,50,8.0); noStroke(); ellipseMode(CENTER); } void draw(){ background(200); translate(0,0,-100); rotateX(PI/8); grid.draw(0,0,0); grid.ripple(x,y,wavespeed); } void mousePressed(){ x = int(mouseX/grid.size); y = int(mouseY/grid.size); grid.waveRadius = 0.0; } class QuadGrid{ float wide,high,size,waveRadius; Vec3 [][] corn; QuadGrid(int wide, int high, float size){ this.wide = wide; this.high = high; this.size = size; this.waveRadius = 0.0; corn = new Vec3[wide][high]; for(int i = 0; i < wide; i++){ for(int j = 0; j < high; j++){ corn[i][j] = new Vec3(i*size, j*size, 0.0); } } } void draw(float x, float y, float z){ pushMatrix(); translate(x,y,z); for(int i = 0; i < wide-1; i++){ for(int j = 0; j < high-1; j++){ zQuad( corn[i][j].x,corn[i][j].y,corn[i][j].z, corn[i+1][j].x,corn[i+1][j].y,corn[i+1][j].z, corn[i+1][j+1].x,corn[i+1][j+1].y,corn[i+1][j+1].z, corn[i][j+1].x,corn[i][j+1].y,corn[i][j+1].z ); } } popMatrix(); } void ripple(int x, int y, float speed){ for(int i = 0; i < wide; i++){ for(int j = 0; j < high; j++){ float t = dist(x,y,i,j); if(t < waveRadius && t > waveRadius - (wavelength)){ corn[i][j].z = waveheight(waveRadius-t); } else{ corn[i][j].z = 0.0; } } } waveRadius += speed; } } float waveheight(float radius){ return sin((TWO_PI/wavelength)*radius)*amplitude; } static class Vec3{ float x, y, z; Vec3(){ } Vec3(float x, float y, float z){ this.x = x; this.y = y; this.z = z; } } void zQuad( float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4 ){ beginShape(QUADS); texture(map); vertex(x1,y1,z1,x1,y1); vertex(x2,y2,z2,x2,y2); vertex(x3,y3,z3,x3,y3); vertex(x4,y4,z4,x4,y4); endShape(); }