Documentation000_upload
Transform your PDFs into Flipbooks and boost your revenue!
Leverage SEO-optimized Flipbooks, powerful backlinks, and multimedia content to professionally showcase your products and significantly increase your reach.
// Claus Rytter Bruun de Neergaard
// www.clausclaus.com, March, 2013
// Tested in Processing 2.0b8
// AGENT BEHAVIOR, TWO-DIMENSIONAL WORLD
// VARS /////////////////////////////////////////////////////////////////
int na = 200;
// number of agents
float range = 125.0;
// range of each agent
float sepscale = 0.5;
// separation scale
float aliscale = 10.5;
// alignment scale
float cohscale = 7.5;
// cohesion scale
color acolor = color(100);
// agent color
float aradius = 7.5;
// agent size
boolean connect = true;
ArrayList agents = new ArrayList();
// determins if connections are drawn
// an ArrayList to store all agents
// SETUP ////////////////////////////////////////////////////////////////
void setup() {
size(1189, 841);
background(230);
smooth();
ellipseMode(CENTER);
for (int i = 0; i < na; i++) {
agents.add(new Agent());
}
}
// DRAW /////////////////////////////////////////////////////////////////
void draw() {
background(230);
// create trail for each agent
noStroke();
// calling functions of all of the objects in the ArrayList
for (int i = 0; i < agents.size(); i++) {
Agent a = (Agent) agents.get(i);
a.update(agents);
}
// draw connections
if (connect == true) {
for (int i = 0; i < agents.size(); i++) {
Agent ca = (Agent) agents.get(i);
for (int j = i; j < agents.size(); j++) {
Agent oa = (Agent) agents.get(j);
if (dist(ca.loc.x, ca.loc.y, oa.loc.x, oa.loc.y) < (range/2)) {
stroke(150);
strokeWeight(0.5);
line(ca.loc.x, ca.loc.y, oa.loc.x, oa.loc.y);
}
}
}
}
}
// KEYPRESSED ///////////////////////////////////////////////////////////
void keyPressed() {
// enable or disable connections
if (key == ‘1’) {
connect = true;
}
else if (key == ‘2’) {
connect = false;
}
}
class Agent {
PVector loc, vel, acc, ploc;
float maxforce, maxvel;
Agent() {
// three vectors to describe agent loc, vel and acc
loc = new PVector(random(0, width), random(0, height));
vel = new PVector(0, 0);
acc = new PVector(0, 0);
ploc = loc;
// maxforce makes sure that not all agents move with same speed
//maxforce = random(0.10, 0.75);
maxvel = random(3.5, 10.5);
}
// UPDATE /////////////////////////////////////////////////////////////
void update(ArrayList pop) {
// update the movement
animate(pop);
// update position
vel.add(acc);
vel.limit(maxvel);
loc.add(vel);
acc.set(0, 0, 0);
// standard update functions
edges();
display();
}
// add acceleration to velocity (increase speed)
// make sure there is a movement speed limit
// add velocity to location
// make sure we set acceleration back to zero
// ANIMATE ////////////////////////////////////////////////////////////
void animate(ArrayList pop) {
// calculate the steering vectors
PVector sep = separation(pop);
PVector coh = cohesion(pop);
PVector ali = alignment(pop);
// scale all vectors
sep.mult(sepscale);
coh.mult(cohscale);
ali.mult(aliscale);
// add all steering vectors to movement
acc.add(sep);
acc.add(coh);
acc.add(ali);
}
// EDGES //////////////////////////////////////////////////////////////
void edges() {
if (loc.x > width) {
loc.x = 0;
}
else if (loc.x < 0) {
loc.x = width;
}
if (loc.y > height) {
loc.y = 0;
}
else if (loc.y < 0) {
loc.y = height;
}
}
// DISPLAY ////////////////////////////////////////////////////////////
void display() {
fill(0, 0, 150, 50);
strokeWeight(0.1);
stroke(acolor);
ellipse(loc.x, loc.y, maxvel*8.25, maxvel*8.25);
strokeWeight(3.5);
point(loc.x, loc.y);
}
// RULE 1 - SEPARATION ////////////////////////////////////////////////
PVector separation(ArrayList pop) {
PVector sum = new PVector();
// vector to return
int n = 0;
// counter
for (int i = 0; i < pop.size(); i++) {
Agent a = (Agent) pop.get(i);
float d = loc.dist(a.loc);
// if dist is within range, and larger than zero
if ((d > 0) && (d < range/3)) {
// calculate vector pointing away from neighbor(s)
sum = loc.get();
sum.sub(a.loc);
sum.normalize();
sum.mult(1/d);
n++;
}
}
// calculate average (based on how many agents within range)
if (n > 0) {
sum.mult(1/float(n));
}
return sum;
}
// return the vector
// RULE 2 - COHESION //////////////////////////////////////////////////
PVector cohesion(ArrayList pop) {
PVector sum = new PVector();
// vector to return
int n = 0;
// counter
for (int i = 0; i < pop.size(); i++) {
Agent a = (Agent) pop.get(i);
float d = loc.dist(a.loc);
// if dist is within range, and larger than zero
if ((d > 0) && (d < range)) {
sum.add(a.loc);
n++;
}
}
// calculate average (based on how many agents within range)
if (n > 0) {
sum.mult(1/float(n));
sum = steer(sum, true);
}
return sum;
}
// return the vector
// RULE 3 - ALIGNMENT /////////////////////////////////////////////////
PVector alignment(ArrayList pop) {
PVector sum = new PVector();
// vector to return
int n = 0;
// counter
for (int i = 0; i < pop.size(); i++) {
Agent a = (Agent) pop.get(i);
float d = loc.dist(a.loc);
// if dist is within range, and larger than zero
if ((d > 0) && (d < range)) {
sum.add(a.vel);
n++;
}
}
// calculate average (based on how many agents within range)
if (n > 0) {
sum.mult(1/float(n));
sum.limit(maxforce);
}
return sum;
}
// return the vector
// (RULE 4) - STEER ///////////////////////////////////////////////////
PVector steer(PVector target, boolean slow) {
PVector steerforce;
// the steering vector
target.sub(loc);
float m = target.mag(); // calc the magnitude of the vector
// if dist is within range, and larger than zero (zero being itself)
if (m > 0 && m < range) {
target.normalize();
// calc deceleration if slow is on, else, just continue
if ((slow == true) && (m < (range/2))) {
target.mult(maxvel * (range/width));
}
else {
target.mult(maxvel);
}
target.sub(vel);
steerforce = target.get();
steerforce.limit(maxforce);
} else {
steerforce = new PVector(0, 0);
}
return steerforce;
}
}
// return the vector
code studies --- 12 | 29