// 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 agentsfloat range = 125.0;// range of each agentfloat sepscale = 0.5;// separation scalefloat aliscale = 10.5;// alignment scalefloat cohscale = 7.5;// cohesion scalecolor acolor = color(100);// agent colorfloat aradius = 7.5;// agent sizeboolean 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 agentnoStroke();// calling functions of all of the objects in the ArrayListfor (int i = 0; i < agents.size(); i++) {Agent a = (Agent) agents.get(i);a.update(agents);}// draw connectionsif (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 connectionsif (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 accloc = 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 movementanimate(pop);// update positionvel.add(acc);vel.limit(maxvel);loc.add(vel);acc.set(0, 0, 0);// standard update functionsedges();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 vectorsPVector sep = separation(pop);PVector coh = cohesion(pop);PVector ali = alignment(pop);// scale all vectorssep.mult(sepscale);coh.mult(cohscale);ali.mult(aliscale);// add all steering vectors to movementacc.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 returnint n = 0;// counterfor (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 zeroif ((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 returnint n = 0;// counterfor (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 zeroif ((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 returnint n = 0;// counterfor (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 zeroif ((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 vectortarget.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 continueif ((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 vectorcode studies --- 12 | 29
SCENARIO 1Defined number of agents in a two dimensionalspace, random point of initiation. Eachagent is visualized as a point in space.Subsequent patterns of movement based onseparation. There are no external relations,only internal relations define the movementof each agent.code studies --- 13 | 29