Processing – Boid Steering v1
Posted By: Jordan ParsonsThis is my attempt to create a class of creatures that I can manipulate with different forces and rules. I am doing this as a base to create a pattern for an upcoming project. I have the basics down, but the real trouble for me is collision detection, but I am working through it. I have followed a lot of tutorials, and I think I am getting close, but it’s still rather glitchy. See for yourself, grab the source and un-quote //collide(boids);. Any tips would be greatly appreciated, and source after the jump.
http://jordanparsons.com/processing/boid_steering_v1/

Boid Steering:
flock flock;
void setup(){
flock = new flock();
size(700,700);
background(0);
for(int i=0; i < 100; i++){
if(i<1){
flock.addBoid(new boid(new PVector(width/2,height/2),2.0,.5,i,#0000ff,255));
}else{
flock.addBoid(new boid(new PVector(width/2,height/2),2.0,.5,i,125,255));
}
}
smooth();
}
void draw(){
background(0);
flock.run();
}
Boid:
class boid{
PVector loc, acc, vel;
float r, maxforce, maxspeed, theata, l;
int boidColor, strokeColor, id;
boid(PVector l, float ms, float mf, int ident, int bc, int sc){
acc = new PVector(0,0);
vel = new PVector(random(-1,1),random(-1,1));
loc = l.get();
r=20;
maxspeed = ms;
maxforce = mf;
boidColor = bc;
strokeColor = sc;
id=ident;
}
void run(ArrayList boids){
flock(boids);
update();
edge();
//collide(boids);
render();
}
void flock(ArrayList boids){
PVector wan, sep, mou, coh;
mou = steer(new PVector(mouseX,mouseY),true);
wan = steer(wander(),false);
sep = separate(boids);
coh = cohesion(boids);
sep.mult(10);
wan.mult(.5);
mou.mult(1);
coh.mult(.5);
acc.add(sep);
acc.add(wan);
//acc.add(mou);
acc.add(coh);
}
void edge(){
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;
}
void update() {
vel.add(acc);
vel.limit(maxspeed);
loc.add(vel);
acc.mult(0);
}
void render(){
theata = vel.heading2D()+PI/2;
l=r*vel.mag();
fill(boidColor);
stroke(strokeColor);
pushMatrix();
translate(loc.x,loc.y);
rotate(theata);
noFill();
/* beginShape(TRIANGLES);
vertex(0,-r*2);
vertex(-r,r*2);
vertex(r,r*2);
endShape();*/
ellipseMode(CENTER);
ellipse(0,0,r,r);
stroke(boidColor);
line(0,0,0,-r/1.5);
popMatrix();
}
PVector steer(PVector target, boolean slow){
PVector steer, desired;
float d;
desired = PVector.sub(target,loc);
d = desired.mag();
if(d>0){
desired.normalize();
if ((slow) && (d < 100.0f)){
desired.mult(maxspeed*(d/100.0f));
}
else{
desired.mult(maxspeed);
}
steer = PVector.sub(desired,vel);
steer.limit(maxforce);
}
else{
steer = new PVector(0,0);
}
return steer;
}
PVector wander(){
float wanderR, wanderD, change, wandertheata;
PVector circleloc, circleoffset,target;
wandertheata=random(-90,90);
wanderR=16;
wanderD=60;
change=.25;
wandertheata+=random(-change,change);
circleloc = vel.get();
circleloc.normalize();
circleloc.mult(wanderD);
circleloc.add(loc);
circleoffset = new PVector(wanderR*cos(wandertheata),wanderR*sin(wandertheata));
target = PVector.add(circleloc,circleoffset);
return target;
}
PVector separate(ArrayList boids){
float desiredseparation = 2*r;
PVector sum = new PVector(0,0);
int count = 0;
for(int i=0; i < boids.size(); i++){
boid other = (boid) boids.get(i);
float d = loc.dist(other.loc);
if((d > 0) && (d < desiredseparation)){
PVector diff = loc.sub(loc,other.loc);
diff.normalize();
diff.div(d);
sum.add(diff);
count++;
}
}
if(count > 0){
sum.div(count);
}
return sum;
}
void collide(ArrayList boids){
float desiredseparation = r;
PVector sum = new PVector(0,0);
int count = 0;
for(int i=0; i < boids.size(); i++){
boid other = (boid) boids.get(i);
float d = loc.dist(other.loc);
if((d > 0) && (d < desiredseparation)){
PVector diff = loc.sub(loc,other.loc);
diff.normalize();
diff.div(d);
vel=diff.get();
}
}
}
PVector cohesion (ArrayList boids) {
float neighbordist = r*2;
PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations
int count = 0;
for (int i = 0 ; i < boids.size(); i++) {
boid other = (boid) boids.get(i);
float d = loc.dist(other.loc);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.loc); // Add location
count++;
}
}
if (count > 0) {
sum.div((float)count);
return steer(sum,false); // Steer towards the location
}
return sum;
}
}
flock:
class flock{
ArrayList boids;
flock(){
boids = new ArrayList();
}
void run(){
for(int i=0; i < boids.size(); i++){
boid b = (boid) boids.get(i);
b.run(boids);
}
}
void addBoid(boid b){
boids.add(b);
}
}
No Comments »
No comments yet.
RSS feed for comments on this post. TrackBack URL




