public class Boid {
  float r1 = 40;
  float r2 = 80;
  float r3 = 160;
  
  float x,y;
  float vx, vy;
  Boid[] others;
  
  public Boid( float x, float y, float vx, float vy, Boid[] others ) {
    this.x = x;
    this.y = y;
    this.vx = vx;
    this.vy = vy;
    this.others = others;
  }
  
  void boo() {
    vx = random( -25, 25 );
    vy = random( -25, 25 );
  }
  
  public void update() {
    sep();
    align();
    coh();
    
    float l = sqrt( sq( vx ) + sq ( vy ));
    if (l > 4 ) {
      vx = 0.9 * vx;
      vy = 0.9 * vy;
    }
    
    x += vx;
    y += vy;    
  
    if (x > width - 30 ) { vx -= 2; }
    if (x < 30 ) { vx += 2; }
    if (y > height -30 ) {vy -= 2; }
    if (y < 30) { vy += 2; }
  }
  
  public void sep() {
    int count = 0;
    float sx = 0;
    float sy = 0;
    
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ));
      if (d < r1 && this != others[i] ) {
        count++;
        sx += others[i].x;
        sy += others[i].y;
      }
    }
    
    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;
      
      float l = sqrt( sq( sx ) + sq ( sy ));
      sx = 1.2 * sx / l;
      sy = 1.2 * sy / l;
      
    }
    
    vx += sx;
    vy += sy;
  }
  
  public void align() {
    int count = 0;
    float dx = 0;
    float dy = 0;
    
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ));
      if (d < r2 && this != others[i] ) {
        count++;
        dx += others[i].vx;
        dy += others[i].vy;
      }
    }
    
    if ( count  > 0 ){
      dx = dx / count;
      dy = dy / count;    
      float l = sqrt( sq( dx ) + sq ( dy ));
      dx = dx / l;
      dy = dy / l;  
    }
    
    vx += dx;
    vy += dy;
  }
  
  public void coh() {
    int count = 0;
    float sx = 0;
    float sy = 0;
    
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ));
      if (d < r3  && d > r1 && this != others[i] ) {
        count++;
        sx += others[i].x;
        sy += others[i].y;
      }
    }
    
    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;
      
      float l = sqrt( sq( sx ) + sq ( sy ));
      sx = sx / l;
      sy = sy / l;
      
    }
    
    vx -= sx;
    vy -= sy;
  }
  
  
  public void draw() {
    fill(255);
    stroke( 127 );
    
    pushMatrix();
    translate( x, y );
    rotate( atan( vy/vx ) + ( vx < 0  ? PI : 0 ));
    beginShape();
    
    vertex( -15, -5 );
    vertex( -15, 5 );
    vertex( 15, 5 );
    vertex( 15, -5 );

    endShape(CLOSE);
    popMatrix();
  }
}
