patttt
YaBB Newbies
Offline
Posts: 6
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,