Go Jump off a Bridge

In Nature of Code, we learned how to simulate forces acting on objects. After playing with some examples with drag forces in liquids and air, I used these principles to make a program inspired by some photographs I took during a trip to Portugal in 2010. There was a bridge in the city of Porto that the local kids liked to jump off into the river below. I have some great photos of the kids suspended in mid-jump. I used these photos to make the divers in my Processing sketch.

Here is the code for the main sketch:

[code lang="java"]//Kim Ash
//Divers experience drag and other forces as they fall into the sea.

Liquid liquid;
Mover diver1;
Mover diver2;

void setup()
{
  size(800, 600);
  background(171, 241, 250);
  liquid = new Liquid(0, 350, width, 250, 0.4);
  
  diver1 = new Mover(4, 250, 0);
  diver2 = new Mover(5, 500, 0);
}

void draw()
{
  background(171, 241, 250);
  
  PVector wind = new PVector(-0.004,0);
  PVector gravity = new PVector(0,0.2);
  
  liquid.render();
  
  if (liquid.contains(diver1)) {
      PVector drag = liquid.drag(diver1);
      diver1.applyForce(drag);
    }

    diver1.applyForce(wind);
    diver1.applyForce(gravity);

    diver1.update();
    diver1.display1();
    diver1.checkEdges();
    
    if (liquid.contains(diver2)) {
      PVector drag = liquid.drag(diver2);
      diver2.applyForce(drag);
    }

    diver2.applyForce(wind);
    diver2.applyForce(gravity);

    diver2.update();
    diver2.display2();
    diver2.checkEdges();
}[/code]

This is the code for the diver object:

[code lang="java"]PImage jumper1; 
PImage jumper2;

class Mover {

  PVector location;
  PVector velocity;
  PVector acceleration;
  float mass;

  Mover(float m, float x , float y) {
    mass = m;
    location = new PVector(x,y);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
  }
  
  void applyForce(PVector force) {
    PVector f = PVector.div(force,mass);
    acceleration.add(f);
  }
  
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);
  }

  void display1() {
    jumper1 = loadImage("jumper1.png");
    image(jumper1, location.x, location.y);
  }
  
  void display2() {
    jumper2 = loadImage("jumper2.png");
    image(jumper2, location.x, location.y);
  }

  void checkEdges() {

    if (location.x > width) {
      location.x = 0;
    } else if (location.x < 0) {
      location.x = width;
    }

    if (location.y > height-160) {
      velocity.y *= -1.3;
      //location.y = height;
    }

  }

}[/code]

And this is the code for the liquid object:

[code lang="java"]class Liquid {

  float x;
  float y;
  float w;
  float h;
  float c;

  Liquid(float x_, float y_, float w_, float h_, float c_) {
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    c = c_;
  }

  boolean contains(Mover m) {
    PVector l = m.location;
    if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
      return true;
    }  
    else {
      return false;
    }
  }

  PVector drag(Mover m) {
    float speed = m.velocity.mag();
    float dragMagnitude = -1 * c * speed * speed;

    PVector drag = m.velocity.get();
    drag.normalize();
    drag.mult(dragMagnitude);
    
    return drag;
  }

  void render() {
    noStroke();
    fill(33,73, 137, 80);
    rectMode(CORNER);
    rect(x,y,w,h);
  }

}[/code]