//created=19 Dec 06
//description=Fluid simulator lets you create waves for surfing stick figures.
//title=Surfing
//publish=true
 
 
int res = 110; //it helps if this is a factor of the screenwidth
float step;
float [] ropeP = new float[res];
float [] ropeV = new float[res];
 
Vector surfers = new Vector();
 
void setup(){
 
size(550,500);
size(550,500);
//smooth();
step = width/res;
 
for (int i = 0; i < res; i++){
ropeP[i] = 0;
ropeV[i] = 0;
}
 
for (int i =0; i < 5; i++){
surfers.add(new Surfer(random(0,width)));
}
}
 
 
void draw(){
background(200,200,255);
fill(0,0,100);
//stroke(0);
translate(0,height/2);
//sum forces
ropeP[res-1] = ropeP[res-2];
for (int i = 1; i < res-1; i++){
//there should be some spring theory here, but I really just made some junk up
//I think its a negative feedback type thing. maybe.
ropeV[i] += ((ropeP[i-1] - ropeP[i]) + (ropeP[i+1] - ropeP[i]))/1.05;
ropeV[i] -= ropeP[i]/100.f;
ropeV[i] /= 1.03f;
}
 
for (int i = 1; i < res-1; i++){
ropeP[i] += ropeV[i];
}
beginShape();
for (int i =0; i < res; i++){
vertex(step*i,ropeP[i]);
}
vertex(width,ropeP[res-1]);
vertex(width,height);
vertex(0,height);
endShape();
 
//draw all of the surfers
Surfer bob;
for (int i =0; i < surfers.size(); i++){
bob = (Surfer)surfers.elementAt(i);
bob.draw();
}
 
}
 
void mouseDragged(){
//use a triangle input to avoid oscillations
int where = mouseX/(width/res);
if (mouseX > 2 && mouseX < width - 10){
ropeV[where] += (mouseY-height/2)/10;
ropeV[where-1] += (mouseY-height/2)/20;
ropeV[where+1] += (mouseY-height/2)/20;
}
}
 
void keyPressed(){
if (key == ' '){
surfers.add(new Surfer(random(0,width)));
}
 
}
 
 
class Surfer{
 
float x,dx,y,dy;
 
Surfer(float x){
this.x = x;
dx = 0;
this.y = -10;
}
 
void draw(){
float ang = 0;
if (x/step > 0 && x/step < res - 2){
float waterHeight = ropeP[(int)(x/step)];
if (y < waterHeight){
dy += .1;
}
if (y > waterHeight){
y = waterHeight;
dy = (waterHeight - y);
}
y += dy;
 
//now, ride the wave
if (abs(y - waterHeight) < 5 ){
ang = (ropeP[(int)(x/step)] - ropeP[(int)(x/step+2)])/50;
dx -= ang;
}
}
//hurl stragglers out into the ocean
if (x > width-10) dx = 2;
dx *= .99;
x += dx;
stroke(0);
fill(255);
pushMatrix();
translate(x,y-20);
 
//this is how to draw a stickfigure with a surfboard
rotate(-ang*2);
line(0,0,0,15);
line(0,15,-5,20);
line(0,15,5,20);
line(-5,7,5,7);
ellipse(0,0,7,7);
line(-1,1,1,1);
line(-1,-1,-1,-1);
line(1,-1,1,-1);
fill(200,200,0);
ellipse(0,20,30,2);
popMatrix();
 
}
 
}