move fish get out of the way

http://cmuems.com/2013/a/wp-content/uploads/sites/2/2013/10/really.pdf

I heavily borrowed Golan’s repulsion code, mostly because I had to start a new one today (the one I was working on was on my USB drive, which I had left in a studio class in a locked room… sigh). Because of this, I was determined to at least make the curves look nice. So I spent a lot of time on various fluid shapes I could make, something that would look interesting laser cut:

blarhg

Then with the code, I abused curveVertex to death. That’s basically it, other than some adjustments for the fishies to not intersect with the big fish for the sake of the laser cutter. I also really wanted to make the fishies naturally shy away from the big fish, but didn’t have time to implement it… and I figured that it wouldn’t even show up on the lasercut screen anyway.

//code from Golan Levin; modified for fishies

ArrayList myFishys;

void setup() {
  size(600, 600);
  myFishys = new ArrayList();
  for (int i=0; i<100; i++) {
    float rx = random(width);
    float ry = random(height);
    while(rx > 50 && (ry > 100 && ry < 500)){
      rx = random(width);
      ry = random(height);
    }
    myFishys.add( new Fishy(rx, ry));
  }
}

void draw() {
  background (255);
  stroke(0);
  noFill();
  bigfish();
  float mutualRepulsionAmount = 1.5;
  for (int i=0; i 1.0) {
        float componentInX = dx/dh;
        float componentInY = dy/dh;
        float proportionToDistanceSquared = 1.0/(dh*dh);
        float repulsionForcex = mutualRepulsionAmount * componentInX * proportionToDistanceSquared;
        float repulsionForcey = mutualRepulsionAmount * componentInY * proportionToDistanceSquared;
        ithFishy.addForce( repulsionForcex, repulsionForcey); // add in forces
        jthFishy.addForce(-repulsionForcex, -repulsionForcey); // add in forces
      }
    }
  }
  for (int i=0; i
void bigfish() {
  pushMatrix();
  translate(width/2+200, height/2+20);
  scale(2);
  line(-180, 0, -70, 0);
  bigfishhead();
  bigfishbones();
  pushMatrix();
  translate(0, -20);
  bigfishtail();
  popMatrix();
  popMatrix();
}
void bigfishtail() {
  tail();
  pushMatrix();
  translate(5, 10);
  scale(0.7);
  tail();
  popMatrix();
  pushMatrix();
  rotate(0.5);
  translate(40, 80);
  tail();
  popMatrix();
}
void tail() {
  beginShape();
  curveVertex(-120, 0);
  curveVertex(-120, 0);
  curveVertex(-125, -5);
  curveVertex(-60, -40);
  curveVertex(30, -50);
  curveVertex(30, -50);
  endShape();
  beginShape();
  curveVertex(30, -50);
  curveVertex(30, -50);
  curveVertex(-60, -20);
  curveVertex(-120, 0);
  curveVertex(-120, 0);
  endShape();
}
void bigfishhead() {
  beginShape();
  curveVertex(-170, -40);
  curveVertex(-170, -40);
  curveVertex(-190, -20);  
  curveVertex(-200, 0);
  curveVertex(-190, 20);
  curveVertex(-170, 40);
  curveVertex(-170, 40);
  endShape();
  beginShape();
  curveVertex(-170, -40);
  curveVertex(-170, -40);
  curveVertex(-180, 0);
  curveVertex(-170, 40);
  curveVertex(-170, 40);
  endShape();
}
void bigfishbones()
{
  topbone();
  pushMatrix();
  for (int i = 0; i < 5; i++) {
    scale(0.85);
    topbone();
  }
  popMatrix();
  bottombone();
  for (int j = 0; j< 5; j++) {
    scale(0.85);
    bottombone();
  }
}
void topbone() {
  beginShape();
  curveVertex(-150, -15);
  curveVertex(-150, -15);
  curveVertex(-155, -17);
  curveVertex(-147, -35);
  curveVertex(-150, -42);
  curveVertex(-142, -55);
  curveVertex(-130, -95);
  curveVertex(-125, -100);
  curveVertex(-125, -100);
  endShape();
  beginShape();
  curveVertex(-125, -100);
  curveVertex(-125, -100);
  curveVertex(-150, -15);
  curveVertex(-150, -15);
  endShape();
}
void bottombone() {
  beginShape();
  curveVertex(-150, 20);
  curveVertex(-150, 20);
  curveVertex(-140, 45);
  curveVertex(-135, 53);
  curveVertex(-135, 53);
  endShape();
}
class Fishy {
  float size;
  float px;
  float py;
  float vx;
  float vy;
  float damping;
  boolean bLimitVelocities = true;

  // Constructor for the Fishy
  Fishy (float x, float y) {
    px = x;
    py = y;
    vx = vy = 0;
    damping = 0.96;
    size = random(0.5, 1.5);
  }

  // Add a force in. One step of Euler integration.
  void addForce (float fx, float fy) {
    float ax = fx;
    float ay = fy;
    vx += ax;
    vy += ay;
  }

  // Update the position. Another step of Euler integration.
  void update() {
    vx *= damping;
    vy *= damping;
    limitVelocities();

    px += vx;
    py += vy;
  }

  void limitVelocities() {
    if (bLimitVelocities) {
      float speed = sqrt(vx*vx + vy*vy);
      float maxSpeed = 10;
      if (speed > maxSpeed) {
        vx *= maxSpeed/speed;
        vy *= maxSpeed/speed;
      }
    }
  }

  void render() {
    noFill();
    pushMatrix();
    translate(px, py);
    fishy();
    endShape();
    popMatrix();
  }

  void fishy() {
    scale(size);
    beginShape();
    curveVertex(-10, 0);
    curveVertex(-10, 0);
    curveVertex(-5, -2);
    curveVertex(0, -3);
    curveVertex(5, -2);
    curveVertex(10, 0);
    curveVertex(10, 0);
    curveVertex(13, -3);
    curveVertex(13, -3);
    endShape();
    beginShape();
    curveVertex(-10, 0);
    curveVertex(-10, 0);
    curveVertex(-5, 2);
    curveVertex(0, 3);
    curveVertex(5, 2);
    curveVertex(10, 0);
    curveVertex(10, 0);
    curveVertex(13, 3);
    curveVertex(13, 3);
    endShape();
  }
}