aswartzell.net web

//import peasy.org.apache.commons.math.*;
//import peasy.*;
//import peasy.org.apache.commons.math.geometry.*;
//import toxi.geom.*;

World world1 = new World();
int count = 0;

void setup() {
  
  size(455,455);
  //size(screen.width,screen.height);
  background(255);
  smooth();
  colorMode(HSB);
  frameRate(50);
  
  //cam = new PeasyCam(this,width);
  int n = 10;
  world1.clear();
  for (int i=0;i<100;i++)
    world1.addAgent(new Agent(new Vec3D(random(width/2-n,width/2+n),random(height/2-n,height/2+n),0),5));
  
}


void draw() {
 
  if (mousePressed) {
    world1.addAgent(new Agent(new Vec3D(mouseX,mouseY,0),2));
  }
  world1.run();
  world1.fade(1);
  
//  if (count % 100 == 0)
//    saveFrame(world1.pop.size()+"frame######.png");
  count++;
  
}

void keyPressed() {
  //saveFrame();
  if(key==' ')
    setup();
}
// Vec3D - simple 3D vector class
// processing.unlekker.net

class Vec3D {
  float x,y,z;

  Vec3D() {
    x=0;
    y=0;
    z=0;
  }
  
  Vec3D(float _x,float _y,float _z) {
    x=_x;
    y=_y;
    z=_z;
  }

  Vec3D(Vec3D v) {
    x=v.x;
    y=v.y;
    z=v.z;
  }

  void set(float _x,float _y,float _z) {
    x=_x;
    y=_y;
    z=_z;
  }

  void set(Vec3D v) {
    x=v.x;
    y=v.y;
    z=v.z;
  }

  void add(float _x,float _y,float _z) {
    x+=_x;
    y+=_y;
    z+=_z;
  }

  void add(Vec3D v) {
    x+=v.x;
    y+=v.y;
    z+=v.z;
  }

  void sub(float _x,float _y,float _z) {
    x-=_x;
    y-=_y;
    z-=_z;
  }

  void sub(Vec3D v) {
    x-=v.x;
    y-=v.y;
    z-=v.z;
  }

  void mult(float m) {
    x*=m;
    y*=m;
    z*=m;
  }

  void div(float m) {
    x/=m;
    y/=m;
    z/=m;
  }

  float length() {
    return sqrt(x*x+y*y+z*z);
  }

  void normalize() {
    float l=length();
    if(l!=0) {
      x/=l;
      y/=l;
      z/=l;
    }
  }

  void limit(float max) {
    float l=length();
    if(l>max) {
      normalize();
      mult(max);
    }
  }

  void rotateX(float val) {
    // Floats are not precise enough, so doubles are used for the calculations
    double cosval=Math.cos(val);
    double sinval=Math.sin(val);
    double tmp1=y*cosval - z*sinval;
    double tmp2=y*sinval + z*cosval;

    y=(float)tmp1;
    z=(float)tmp2;
  }

  void rotateY(float val) {
    // Floats are not precise enough, so doubles are used for the calculations
    double cosval=Math.cos(val);
    double sinval=Math.sin(val);
    double tmp1=x*cosval - z*sinval;
    double tmp2=x*sinval + z*cosval;

    x=(float)tmp1;
    z=(float)tmp2;
  }

  void rotateZ(float val) {
    // Floats are not precise enough, so doubles are used for the calculations
    double cosval=Math.cos(val);
    double sinval=Math.sin(val);
    double tmp1=x*cosval - y*sinval;
    double tmp2=x*sinval + y*cosval;

    x=(float)tmp1;
    y=(float)tmp2;
  }
  
  Vec3D copy() {
    return(new Vec3D(x,y,z));
  }
}
class Agent {
  
  Vec3D pos = new Vec3D();
  Vec3D prev = new Vec3D();
  Vec3D vel = new Vec3D();
  Vec3D acc = new Vec3D();
  float maxVel;
  float age = 0;
  
  Agent(Vec3D _pos, float _maxVel){
    pos = _pos.copy();
    maxVel = _maxVel;
    vel = new Vec3D(maxVel,maxVel,0);
    vel.rotateZ(random(0,360));
  }
  
  void update() {
   
    vel.add(acc);
    prev = pos.copy();
    pos.add(vel);
    acc = new Vec3D();
    
    if (age<128)
      age+=.5;
    //borders();
    
  }
  
  // steer
  Vec3D steer(Vec3D target, float threshold, float maxForce) {
    target.sub(pos); 
    float dist = target.length();

    if (dist > 0 && dist < threshold) {
      target.normalize();
      target.mult(maxVel);
      target.sub(vel); 
      target.limit(maxForce); 
    } 
    else {
      target = new Vec3D(0,0,0);
    }
    return target;
  }


  // seek
  void seek(Vec3D target, float threshold,float maxForce) {
    acc.add(steer(target, threshold, maxForce));
  }

  void render(){
    stroke(0,0,0,age);
    strokeWeight(1);
    point(pos.x,pos.y);
    //line(pos.x,pos.y,prev.x,prev.y);
  }
  
  void borders() {
    if (pos.x < 0){ 
      pos.x = pos.x + width;
      prev.x = prev.x + width;
    }
    if (pos.y < 0) { 
      pos.y = pos.y + height;
      prev.y = prev.y + width;
    }
    if (pos.x > width) { 
      pos.x = pos.x - width;
      prev.x = prev.x - width;
    }
    if (pos.y > height) { 
      pos.y = pos.y - height;
      prev.y = prev.y - width;
    }
  }
  
}
class World {

  ArrayList pop = new ArrayList();

  void run() {

    for (int i = 0; i < pop.size(); i++) {
      Agent a = (Agent) pop.get(i);

      int index = 0;
      if (i+1< pop.size()) index = i + 1;
      Agent b = (Agent) pop.get(index);
      if (mouseX<25||mouseX>width-25||mouseY<25||mouseY>height-25)
        a.seek(new Vec3D(width/2, height/2, 0), width*height, 0.025);
      else
        a.seek(new Vec3D(mouseX, mouseY, 0), width*height, 0.025);
      a.seek(b.pos.copy(), width*height, 0.05);
      a.update();
      a.render();
      stroke(0,0,0,20);
      line(a.pos.x,a.pos.y,a.prev.x,a.prev.y);
      line(a.pos.x,a.pos.y,b.pos.x,b.pos.y);
    }
  }

  void addAgent(Agent a) {
    pop.add(a);
  }
  
  void clear(){
    pop.clear();
  }

  void fade(float rate) {

    //fade the trails
    loadPixels();
    for (int i=0; i<width*height; i++) {
      color c = pixels[i];
      if (brightness(c) < 255)
        pixels[i] = color(hue(c), saturation(c), brightness(c)+1*rate);
      if (saturation(c) > 0)
        pixels[i] = color(hue(c), saturation(c)-1*rate, brightness(c));
    }
    updatePixels();
  }
}