• fullscreen
  • Predator.pde
  • Prey.pde
  • PreyPredator3D.pde
  • vAgent.pde
  • vWorld.pde
  • class vAgentPredator extends vAgent{
       
     vAgentPredator(     
         Vec3D _pos, 
         Vec3D _vec, 
         float _maxVel,
         float _maxForce){
           
      super(
         _pos, 
         _vec, 
         _maxVel,
         _maxForce);
         
         drawColor = 0;
         agentType = "vAgentPredator";
         
         vel = new Vec3D(0,0,0);    
      }
     
      void step(vWorld world){ 
        updatePop(world.population);
        vel.addSelf(acc);
        vel.limit(maxVel);  
        pos.addSelf(vel);
        acc = new Vec3D(0,0,0);  // reset acc to 0 each iteration
        borders(envSize);
        render();
     }
     
      void updatePop(ArrayList pop){  
        
       // seek pray
       // find closest agent
       float closestDist = envSize*envSize;
       int closestAgent = 0;
       for(int i = 0; i<pop.size(); i++){
         vAgent other = (vAgent) pop.get(i);
         if(other.agentType == "vAgentPrey"){
           float dist = pos.distanceTo(other.pos);
           if(i > 0){
             if(dist < closestDist){
               closestDist = dist;
               closestAgent = i;
             }
               
           }else{
             closestDist = dist;
             closestAgent = 0;
           }
         }
       }
        
        // seek closest agent
        vAgent other = (vAgent) pop.get(closestAgent);
        Vec3D target = other.pos.copy();
        
        this.seek(target, 300);
      } 
     
     
      void render() {
        strokeWeight(2);
        stroke(0);
        Line3D l = new Line3D(pos,pos.add(vel.normalize().scale(10)));
        gfx.line(l);
        stroke(255,0,0);
        point(pos.x,pos.y,pos.z);
      }
      
    }
    
    class vAgentPrey extends vAgent{
       
     vAgentPrey(     
         Vec3D _pos, 
         Vec3D _vec, 
         float _maxVel,
         float _maxForce){
           
      super(
         _pos, 
         _vec, 
         _maxVel,
         _maxForce);
         
         drawColor = 255;
         agentType = "vAgentPrey";
      }
     
      
       void updatePop(ArrayList pop){  
        
        Vec3D predFlee = this.preditorFlee(pop);
         
        // call population functions
        Vec3D sep = separate(pop);   
        Vec3D ali = align(pop);      
        Vec3D coh = cohesion(pop);   
        
        // weight vector
        sep.scaleSelf(sepScale);
        ali.scaleSelf(aliScale);
        coh.scaleSelf(cohScale);
        
        predFlee.scaleSelf(10);
        
        // add the vectors to acceleration
        acc.addSelf(sep);
        acc.addSelf(ali);
        acc.addSelf(coh);
        
        acc.subSelf(predFlee);
      } 
      
      Vec3D preditorFlee(ArrayList pop){
       // find closest agent
       float closestDist = envSize*envSize;
       int closestAgent = 0;
       for(int i = 0; i<pop.size(); i++){
         vAgent other = (vAgent) pop.get(i);
         if(other.agentType == "vAgentPredator"){
           float dist = pos.distanceTo(other.pos);
           if(i > 0){
             if(dist < closestDist){
               closestDist = dist;
               closestAgent = i;
             }
               
           }else{
             closestDist = dist;
             closestAgent = 0;
           }
         }
    
       }
        
        // seek closest agent
        vAgent other = (vAgent) pop.get(closestAgent);
        Vec3D target = other.pos.copy();
        return this.steer(target, 100); 
      
      }
       
    }
    
    import peasy.*;
    import toxi.processing.*;
    import toxi.geom.*;
    
    PeasyCam cam;
    vWorld world1;
    ToxiclibsSupport gfx;
    
    float envSize = 300;
    
    void setup(){
      size(500,500,P3D);
      
      cam = new PeasyCam(this, 1100);
      cam.setMinimumDistance(800);
      cam.setMaximumDistance(1400);
      gfx=new ToxiclibsSupport(this);
      
      world1 = new vWorld();
        
      // create agents
      for (int i = 0; i < 200; i++) {
        world1.addAgent(new vAgentPrey(new Vec3D(random(-250,250),random(-250,250),random(-250,250)), new Vec3D(random(-1,1),random(-1,1),random(-1,1)), 10, 0.1));
      }
      for (int i = 0; i < 10; i++) {
        world1.addAgent(new vAgentPredator(new Vec3D(random(-250,250),random(-250,250),random(-250,250)),new Vec3D(random(-1,1),random(-1,1),random(-1,1)), 12, 1));
      }
    }
    
    
    void draw(){
      background(120);
      world1.addBox(envSize);
      world1.run();
    }
    
    // simple 3D agent class - based on code from dan shiffman
    // roland snooks | kokkugia.com | 2007
    
    
    class vAgent{
      
     Vec3D         acc;
     Vec3D         vel;
     Vec3D         pos;
     Vec3D         vec;
     float        maxVel;
     float        maxForce;
     float        sepScale;
     float        aliScale;
     float        cohScale;
     float        rangeOfVision;
    
     float        wandertheta;
     float        wanderomega;
     
     float        attOffset = 200;
     float        ht = envSize*2;
     int          drawColor;
       
     String       agentType = "vAgent";
     
     Vec3D sumSep = new Vec3D(0,0,0);
     
     // constructor simple
     vAgent(
         Vec3D _pos, 
         Vec3D _vec, 
         float _maxVel,
         float _maxForce){
       
       acc = new Vec3D(0,0,0);
       vel = new Vec3D(random(-1,1),random(-1,1),random(-1,1));    
       pos = _pos.copy();
       vec = _vec.copy();
       maxVel = _maxVel;
       maxForce = _maxForce;
       
       sepScale = 7;
       aliScale = 0.7;
       cohScale = 1;
        
       rangeOfVision = 70; 
    
       drawColor = 255;
       
     }
     
     // constructor complete
      vAgent(
         Vec3D _pos, 
         Vec3D _vec, 
         float _maxVel,
         float _maxForce,
         Vec3D _vel,
         float _sepScale,
         float _aliScale,
         float _cohScale,
         float _rangeOfVision){
       
       acc = new Vec3D(0,0,0);
       vel = _vel.copy();    
       pos = _pos.copy();
       vec = _vec.copy();
       maxVel = _maxVel;
       maxForce = _maxForce;
       
       sepScale = _sepScale;
       aliScale = _aliScale;
       cohScale = _cohScale;
        
       rangeOfVision = _rangeOfVision; 
       drawColor = 255;
     }
     
     
     // calculates new location
     void step(vWorld world){ 
        updatePop(world.population);
        
        vel.addSelf(acc);
        vel.limit(maxVel);  
        pos.addSelf(vel);
        acc = new Vec3D(0,0,0);  // reset acc to 0 each iteration
        
        borders(envSize);
        render();
     }
     
     
     void updatePop(ArrayList pop){  
        
        // call population functions
        Vec3D sep = separate(pop);   
        Vec3D ali = align(pop);      
        Vec3D coh = cohesion(pop);   
        
        // weight vector
        sep.scaleSelf(sepScale);
        ali.scaleSelf(aliScale);
        coh.scaleSelf(cohScale);
        
        // add the vectors to acceleration
        acc.addSelf(sep);
        acc.addSelf(ali);
        acc.addSelf(coh);
      }    
     
     
    
     // steer
     Vec3D steer(Vec3D target, float threshold) {
        target.subSelf(pos); 
        float dist = target.magnitude();
    
        if (dist > 0 && dist < threshold) {
          target.normalize();
          target.scaleSelf(maxVel);
          target.subSelf(vel); 
          target.limit(maxForce); 
        } 
        else {
          target = new Vec3D(0,0,0);
        }
        return target;
      }
    
    
      // seek
      void seek(Vec3D target, float threshold) {
        acc.addSelf(steer(target, threshold));
      }
       
       
      // flee  
      void flee(Vec3D target, float threshold){
        acc.subSelf(steer(target, threshold));
      }   
      
      
      // wander
      void wander() {
        float wanderR =8;         
        float wanderD = 60;         
        float change = 0.1;
        wandertheta += random(-change,change);
        wanderomega += random(-change,change);
    
        Vec3D circleloc = vel.copy(); 
        circleloc.normalize();            
        circleloc.scaleSelf(wanderD);          
        circleloc.addSelf(pos);              
    
        //Vec3D circleOffSet = new Vec3D(wanderR*cos(wandertheta),wanderR*sin(wandertheta),0);
        Vec3D circleOffSet = new Vec3D(wanderR*sin(wandertheta)*cos(wanderomega),wanderR*sin(wandertheta)*sin(wanderomega),wanderR*cos(wandertheta));
        circleOffSet.addSelf(circleloc);
        acc.addSelf(steer(circleOffSet,ht)); 
      }  
    
    
    // separation
      Vec3D separate (ArrayList pop) {
        Vec3D sum = new Vec3D(0,0,0);
        int count = 0;
    
        for (int i = 0 ; i < pop.size(); i++) {
          vAgent other = (vAgent) pop.get(i);
          float dist = pos.distanceTo(other.pos);
          
          if ((dist > 0) && (dist < rangeOfVision/1.5)) {
            Vec3D diff = pos.copy(); 
            diff.subSelf(other.pos);
            diff.normalize();
            diff.scaleSelf(1/dist);          
            sum.addSelf(diff);
            count++;                     
          }
        }
        if (count > 0) {
          sum.scaleSelf(1/(float)count);
        }
        sumSep = sum.copy();
        return sum;
      }
     
     
      // alignment
      Vec3D align (ArrayList pop) {
        Vec3D sum = new Vec3D(0,0,0);
        int count = 0;
        for (int i = 0 ; i < pop.size(); i++) {
          vAgent other = (vAgent) pop.get(i);
          float dist = pos.distanceTo(other.pos);
          if ((dist > 0) && (dist < rangeOfVision)) {
            sum.addSelf(other.vel);
            count++;
          }
        }
        if (count > 0) {
          sum.scaleSelf(1/(float)count);
          sum.limit(maxForce);
        }
        return sum;
      }
    
    
      // cohesion
      Vec3D cohesion (ArrayList pop) {
        Vec3D sum = new Vec3D(0,0,0);   
        int count = 0;
        for (int i = 0 ; i < pop.size(); i++) {
          vAgent other = (vAgent) pop.get(i);
          float dist = pos.distanceTo(other.pos);
          if ((dist > 0) && (dist < rangeOfVision)) {
            sum.addSelf(other.pos); 
            count++;
          }
        }
        if (count > 0) {
          sum.scaleSelf(1/(float)count);
          return steer(sum, ht);
        }
        return sum;
      }
    
    
      void render() {
        strokeWeight(1);
        stroke(255);
        Line3D l = new Line3D(pos,pos.add(vel.normalize().scale(8)));
        gfx.line(l);
        stroke(255);
        point(pos.x,pos.y,pos.z);
      }
      
      
      void borders(float envSize) {
        if (pos.x < -envSize) pos.x = envSize;
        if (pos.y < -envSize) pos.y = envSize;
        if (pos.z < -envSize) pos.z = envSize;
        if (pos.x > envSize) pos.x = -envSize;
        if (pos.y > envSize) pos.y = -envSize;
        if (pos.z > envSize) pos.z = -envSize;
      }
    }
    
    class vWorld {
      ArrayList population;
      
      vWorld() {
         population = new ArrayList();
      }
    
      // cycles through each agent passing the population to it
      void run(){
        for (int i = 0; i < population.size(); i++) {
          vAgent a = (vAgent) population.get(i);  
          a.step(this); 
        }
      }
    
      // adds an agent to the population
      void addAgent(vAgent a) {
        population.add(a);
      }
      
      void addBox(float env){
        noFill();
        stroke(0);
        strokeWeight(1);
        box(env*2);
      }
      
    }
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Junichiro Horikawa

    Prey & Predator 3D

    Add to Faves Me Likey@! 3
    You must login/register to add this sketch to your favorites.

    simple swarm simulation in 3d

    So nice. This sketch rocks. Could you make it interactive?
    You need to login/register to comment.