Autonomous Agents

I added some element of “steering” to a previous sketch to create a group of sea creatures or boids that move through the screen. The three forces applied to each boid to create the steering behavior are avoid, approach, and align.




Processing code:

ArrayList boids = new ArrayList(); int boidNum = 15; // amount of boids float timer; color[] colors = new color[3]; void setup() { frameRate(30); size(700, 700); colors[0] =color(240,110,110, 150); // pink colors[1] = color(250,190,120, 140); // yellow colors[2] = color(160,80,100, 150); // purple for (int i=0; i boids) { avoidForce(boids); approachForce(boids); alignForce(boids); } void update() { vel.add(acc); loc.add(vel); acc.mult(0); vel.limit(5); // Check edges if (loc.x<=0) { loc.x = width; } if (loc.x>width) { loc.x = 0; } if (loc.y<=0) { loc.y = height; } if (loc.y>height) { loc.y = 0; } } void applyF(PVector force) { //F=ma force.div(mass); acc.add(force); } void display() { update(); fill(cl); noStroke(); ellipse(loc.x, loc.y, mass, mass); ellipse(loc.x, loc.y, mass*.8, mass*.8); float theta = vel.heading2D(); // LEGS pushMatrix(); translate(loc.x, loc.y); rotate(theta); stroke(cl); strokeWeight(5); displayLeg(mass * 0.75, 0.75, 0.3); displayLeg(mass * 0.75, 0.25, 0.1); displayLeg(mass * 0.75, -0.25, -0.1); displayLeg(mass * 0.75, -0.75, -0.3); popMatrix(); } void displayLeg(float length, float angle, float delay) { float rotation = 0.5 * sin(3 * (timer - delay)); float leftAngle = angle + rotation; float rightAngle = PI - angle - rotation; line(0, 0, length * sin(leftAngle), length * cos(leftAngle)); line(0, 0, length * sin(rightAngle), length * cos(rightAngle)); } // AVOID void avoidForce(ArrayList boids) { float count = 0; // how many boids are close PVector locSum = new PVector(); // store positions for (Boid other : boids) { int separation = mass + 60; // separation, using mass as reference PVector dist = PVector.sub(other.getLoc(), loc); //distance to other boid float d = dist.mag(); if (d != 0 && d0) { locSum.div(count); PVector avoidVec = PVector.sub(loc, locSum); avoidVec.limit(maxForce*3); applyF(avoidVec); } } // APPROACH void approachForce(ArrayList boids) { float count = 0; // keep track of boids PVector locSum = new PVector(); for (Boid other : boids) { int approachRadius = mass + 60; PVector dist = PVector.sub(other.getLoc(), loc); float d = dist.mag(); if (d != 0 && d0) { locSum.div(count); PVector approachVec = PVector.sub(locSum, loc); approachVec.limit(maxForce); applyF(approachVec); } } // ALIGN void alignForce(ArrayList boids) { float count = 0; // keep track of how many boids are in sight. PVector velSum = new PVector(); // store vels of boids in sight. for (Boid other : boids) { int alignRadius = mass + 100; PVector dist = PVector.sub(other.getLoc(), loc); float d = dist.mag(); if (d != 0 && d0) { velSum.div(count); PVector alignVec = velSum; alignVec.limit(maxForce); applyF(alignVec); } } PVector getLoc() { return loc; } PVector getVel() { return vel; } }

Leave a Reply