public class Boid {
  float r1 = 40;
  float r2 = 80;
  float r3 = 160;
  
  float x,y,z;
  float vx, vy,vz;
  Boid[] others;
  
  public Boid( float x, float y, float z, float vx, float vy, float vz, Boid[] others ) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.vx = vx;
    this.vy = vy;
    this.vz = vz;
    this.others = others;
  }
  
  void boo() {
    vx = random( -25, 25 );
    vy = random( -25, 25 );
    vz = random( -25, 25 );
  }
  
  public void update() {
    
    sep();
    align();
    coh();
    
    float l = sqrt( sq( vx ) + sq ( vy ) + sq( vz));
    if (l > 4 ) {
      vx = 0.9 * vx;
      vy = 0.9 * vy;
      vz = 0.9 * vz;
    }
    
    x += vx;
    y += vy;    
    z += vz;
  
    if (x > width/2 - 15 ) { vx -= 2; }
    if (x < -width/2 + 15 ) { vx += 2; }
    if (y > height/2 -60 ) {vy -= 2; }
    if (y < -height/2 -90) { vy += 2; }
    if (z > width/2 - 15) { vz -= 2; }
    if (z < -width/2 + 15) { vz += 2; } 
   
  }
  
  public void sep() {
    int count = 0;
    float sx = 0;
    float sy = 0;
    float sz = 0;
    
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ) + sq( z - others[i].z));
      if (d < r1 && this != others[i] ) {
        count++;
        sx += others[i].x;
        sy += others[i].y;
        sz += others[i].z;
      }
    }
    
    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;
      sz = z - sz / count;
      float l = sqrt( sq( sx ) + sq ( sy ) + sq(sz));
      sx = 1.2 * sx / l;
      sy = 1.2 * sy / l;
      sz = 1.2 * sz / l;
      
    }
    
    vx += sx;
    vy += sy;
    vz += sz;
  }
  
  public void align() {
    int count = 0;
    float dx = 0;
    float dy = 0;
    float dz = 0;
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ) + sq( z - others[i].z));
      if (d < r2 && this != others[i] ) {
        count++;
        dx += others[i].vx;
        dy += others[i].vy;
        dz += others[i].vz;
      }
    }
    
    if ( count  > 0 ){
      dx = dx / count;
      dy = dy / count;    
      dz = dz / count;
      float l = sqrt( sq( dx ) + sq ( dy ) + sq( dz ));
      dx = dx / l;
      dy = dy / l;  
      dz = dz / l;
    }
    
    vx += dx;
    vy += dy;
    vz += dz;
  }
  
  public void coh() {
    int count = 0;
    float sx = 0;
    float sy = 0;
    float sz = 0;
    
    for ( int i = 0; i < others.length; i ++ ) {
      
      float d = sqrt( sq( x - others[i].x ) + sq( y - others[i].y ) + sq( z - others[i].z));
      if (d < r3  && d > r1 && this != others[i] ) {
        count++;
        sx += others[i].x;
        sy += others[i].y;
        sz += others[i].z;
      }
    }
    
    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;
      sz = z - sz / count;
      
      float l = sqrt( sq( sx ) + sq ( sy ) + sq(sz));
      sx = sx / l;
      sy = sy / l;
      sz = sz / l;
      
    }
    
    vx -= sx;
    vy -= sy;
    vz -= sz;
  }
  
  
}
