We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › wander, boild and flock from daniel shiffman!
Page Index Toggle Pages: 1
wander, boild and flock from daniel shiffman! (Read 914 times)
wander, boild and flock from daniel shiffman!
Nov 18th, 2009, 4:09pm
 
hello,
I was wondering how to combine wander ,boid and flocking code together?
I have tried to combine wander and boid and it'd work.  Here is the code

// Wander
// Daniel Shiffman
// The Nature of Code


Boid wanderer;
boolean debug = true;
boolean seek = false;

void setup() {
 size(400,400);
 wanderer = new Boid(new PVector(width/2,height/2),3.0,0.1);
 smooth();
 
}

void draw() {
 background(255);

//case 1 agent wander around
if(!seek)wanderer.wander();
  wanderer.run();
//case 2 agent arrive at target
 if(seek) wanderer.arrive(new PVector(mouseX,mouseY));
 
}

void mousePressed() {
 debug = !debug;
 //agent seeking a target
 if (key == 's' || key == 'S') {
  seek = !seek;
 }else{
   debug = !debug;
 }

}


// The "Boid" class (for wandering)

class Boid {
 //feilds
 PVector loc;
 PVector vel;
 PVector acc;
 float r;
 float wandertheta;
 float maxforce;    // Maximum steering force
 float maxspeed;    // Maximum speed
//constructor
 Boid(PVector l, float ms, float mf) {
   acc = new PVector(0,0);
   vel = new PVector(0,0);
   loc = l.get();
   r = 3.0;
   wandertheta = 0.0;
   maxspeed = ms;
   maxforce = mf;
 }
 
 void run() {
   update();
   borders();
   render();
 }
//----------------------------------Start Flock----------------------------------------
// We accumulate a new acceleration each time based on three rules
 void flock(ArrayList boids) {
   PVector sep = separate(boids);   // Separation
   PVector ali = align(boids);      // Alignment
   PVector coh = cohesion(boids);   // Cohesion
   // Arbitrarily weight these forces
   sep.mult(1.5);
   ali.mult(1.0);
   coh.mult(1.0);
   // Add the force vectors to acceleration
   acc.add(sep);
   acc.add(ali);
   acc.add(coh);
 }
// ----------------------------------End Flock----------------------------------------
 // Method to update location
 void update() {
   // Update velocity
   vel.add(acc);
   // Limit speed
   vel.limit(maxspeed);
   loc.add(vel);
   // Reset accelertion to 0 each cycle
   acc.mult(0);
 }

 void seek(PVector target) {
   acc.add(steer(target,false));
 }
/*arrive change*/
 void arrive(PVector target) {
   acc.add(steer(target,true));
 }
 /*---------------------------------WANDE START------------------------------------------------------ */
 void wander() {
   float wanderR = 16.0f;         // Radius for our "wander circle"
   float wanderD = 50.0f;         // Distance for our "wander circle"
   float change = 0.25f;
   wandertheta += random(-change,change);     // Randomly change wander theta

   // Now we have to calculate the new location to steer towards on the wander circle
   PVector circleloc = vel.get();  // Start with velocity
   circleloc.normalize();            // Normalize to get heading
   circleloc.mult(wanderD);          // Multiply by distance
   circleloc.add(loc);               // Make it relative to boid's location
   
   PVector circleOffSet = new PVector(wanderR*cos(wandertheta),wanderR*sin(wandertheta));
   PVector target = PVector.add(circleloc,circleOffSet);
   acc.add(steer(target,false));  // Steer towards it
   
   // Render wandering circle, etc.
   if (debug) drawWanderStuff(loc,circleloc,target,wanderR);
 
 }  
 /*---------------------------------WANDE ENDT------------------------------------------------------ */
 // A method that calculates a steering vector towards a target
 // Takes a second argument, if true, it slows down as it approaches the target
 PVector steer(PVector target, boolean slowdown) {
   PVector steer;  // The steering vector
   PVector desired = PVector.sub(target,loc);  // A vector pointing from the location to the target
   float d = desired.mag(); // Distance from the target is the magnitude of the vector
   // If the distance is greater than 0, calc steering (otherwise return zero vector)
   if (d > 0) {
     // Normalize desired
     desired.normalize();
     // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
     if ((slowdown) && (d < 100.0f)) desired.mult(maxspeed*(d/100.0f)); // This damping is somewhat arbitrary
     else desired.mult(maxspeed);
     // Steering = Desired minus Velocity
     steer = PVector.sub(desired,vel);
     steer.limit(maxforce);  // Limit to maximum steering force
   } else {
     steer = new PVector(0,0);
   }
   return steer;
 }
 
 void render() {
   // Draw a triangle rotated in the direction of velocity
   float theta = vel.heading2D() + radians(90);
   fill(175);
   stroke(0);
   pushMatrix();
   translate(loc.x,loc.y);
   rotate(theta);
   beginShape(TRIANGLES);
   vertex(0, -r*2);
   vertex(-r, r*2);
   vertex(r, r*2);
   endShape();
   popMatrix();
 }
 
 // Wraparound
 void borders() {
   if (loc.x < -r) loc.x = width+r;
   if (loc.y < -r) loc.y = height+r;
   if (loc.x > width+r) loc.x = -r;
   if (loc.y > height+r) loc.y = -r;
 }

}

 /*---------------------------------WANDE CIRCLE---------------------------------------------------- */
// A method just to draw the circle associated with wandering
void drawWanderStuff(PVector loc, PVector circle, PVector target, float rad) {
 stroke(0);
 noFill();
 ellipseMode(CENTER);
 ellipse(circle.x,circle.y,rad*2,rad*2);
 ellipse(target.x,target.y,4,4);
 line(loc.x,loc.y,circle.x,circle.y);
 line(circle.x,circle.y,target.x,target.y);
}

The question is how do i add more boid with flocking behavior.
So, I can control the number of boid which still have an wander or
seek ability.  
flocking code is here.
shiffman.net/teaching/nature/steering
Thanks,
Re: wander, boild and flock from daniel shiffman!
Reply #1 - Nov 22nd, 2009, 12:27am
 
If you paste partial code, and invite the reader to paste together even more code from a .zip on an external site just to get the thing to run, it takes a lot of effort just to get to the point of seeing what the question is...I know this is your first post here and it's tough to know how clear you are being when you're starting out -- just letting you know!

You appear to have removed several functions from Shiffman's "boid" class (separate(), align(), cohesion()) -- which need to be pasted back in just to get this running.  You've also changed the mousePressed code, so that instead of adding a boid to the boid array called "flock," it seems to check for the last key pressed -- that's probably not the behavior you're after.  Creating multiple boids is already part of the boids example code, so that's not an issue -- just reinstate the flock array that you replaced with a single "wanderer" object, and bring back the mousePressed() code that adds a new boid to that array.

As for controlling the behavior of a boid, you could start by defining it as a wanderer or flocker, and representing that type as an integer or boolean.  Variables of this kind are declared inside the boid class -- "float maxspeed" is one such variable, for example.  That lets each boid object "own" its type.  Then you can modifiy the draw() loop to check each boid's type before running the appropriate function.
Page Index Toggle Pages: 1