KAgent example 2d wander

From KokkugiaWiki

a simple agent which seeks and wanders

the kAgent class has an additional method - wander. this gets called from the draw procedure.

simpleAgent wander


sketch

import kGeom.*;

kAgent agent1 = new kAgent(new kVec(250,250), new kVec(1,1), 5, 0.2);

void setup(){
    size(500,500);
    frameRate(30);
    smooth();
}

void draw(){
  background(125);
  
  agent1.seek(new kVec(mouseX,mouseY));
  agent1.wander();
  agent1.update();
  agent1.render();
  
}


kAgent

// simple 2D agent class
// roland snooks | kokkugia.com | 2007
// based on code from daniel shiffman

class kAgent{
  
 kVec         acc;
 kVec         vel;
 kVec         pos;
 kVec         vec;
 float        maxVel;
 float        maxForce;
 float        wandertheta;

 // constructor
 kAgent(
     kVec _pos, 
     kVec _vec, 
     float _maxVel,
     float _maxForce){
   
   acc = new kVec(0,0);
   vel = new kVec(0,0);    
   pos = kVec.clone(_pos);
   vec = kVec.clone(_vec);
   maxVel = _maxVel;
   maxForce = _maxForce;
   
 }
 
 
 // calculates new location
 void update(){  
    vel.plus(acc);
    vel.limit(maxVel);  
    pos.plus(vel);
    acc = new kVec(0,0);  // reset acc to 0 each iteration
    borders();
 }


 // seek
 void seek(kVec target) {
    acc.plus(steer(target));
 }
   

 // steer
 kVec steer(kVec target) {
    kVec steer;  // The steering vector
    target.minus(pos); 
    float distance = target.length();

    if (distance > 0) {
      target.normalize();
      target.scale(maxVel);
      target.minus(vel); 
      //steer = kVec.clone(target); 
      target.limit(maxForce); 

    } 
    else {
      target = new kVec(0,0);
    }
    return target;
  }

  void wander() {
    float wanderR = 16;         // Radius for our "wander circle"
    float wanderD = 60;         // Distance for our "wander circle"
    float change = 0.25;
    wandertheta += random(-change,change);     // Randomly change wander theta

    // Now we have to calculate the new location to steer towards on the wander circle
    kVec circleloc = kVec.clone(vel); 
    //kVec circleloc = vel.clone();  // Start with velocity
    circleloc.normalize();            // Normalize to get heading
    circleloc.scale(wanderD);          // Multiply by distance
    circleloc.plus(pos);               // Make it relative to boid's location

    kVec circleOffSet = new kVec(wanderR*cos(wandertheta),wanderR*sin(wandertheta));
    circleOffSet.plus(circleloc);
    //target = kVec.clone(target);
    acc.plus(steer(circleOffSet));  // Steer towards it

  }  


  void render() {
    fill(200);
    stroke(255);
    ellipse(pos.x,pos.y,10,10);
  }
  
  
  void borders() {
    if (pos.x < 0) pos.x = width;
    if (pos.y < 0) pos.y = height;
    if (pos.x > width) pos.x = 0;
    if (pos.y > height) pos.y = 0;
  }

}


Views