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 › Steering example by Dan Shiffman
Page Index Toggle Pages: 1
Steering example by Dan Shiffman (Read 719 times)
Steering example by Dan Shiffman
Oct 2nd, 2009, 5:27pm
 
Hi, i am trying to understand all the PVector stuff within this steering example by dan shiffman.

this is the example im talking about : http://www.shiffman.net/itp/classes/nature/week06_s09/wander/

there was some seeking code i was able to activat.
What i now trying to do is to add something similar, a fleeing behaviour.
I just cant figure out how to do this.


this is the code with the enabled seeking :

Code:
Boid wanderer;
boolean debug = true;

void setup() {
size(600,600);
wanderer = new Boid(new PVector(width/2,height/2),2.2,20.1);
smooth();
}

void draw() {
background(255);
if(!seek)wanderer.wander();
wanderer.run();
if(seek) wanderer.arrive(new PVector(mouseX,mouseY));
}
boolean seek = false;

void mousePressed() {
debug = !debug;
seek = !seek;
}

// Wander
// Daniel Shiffman <http://www.shiffman.net>
// The Nature of Code

// The "Boid" class (for wandering)

class Boid {

PVector loc;
PVector vel;
PVector acc;
float r;
float wandertheta;
float maxforce; // Maximum steering force
float maxspeed; // Maximum speed

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();
}

// 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));
}

void arrive(PVector target) {
acc.add(steer(target,true));
}

void wander() {
float wanderR = 16.0f; // Radius for our "wander circle"
float wanderD = 55.0f; // Distance for our "wander circle"
float change = 0.3f;
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);

}

// 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;
}

}


// 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);
}




Page Index Toggle Pages: 1