class Spider { PVector loc; PVector acc; PVector vel; PVector lastloc; float rad = 2; float alpha; float maxspeed = 3; float maxforce = 1; Spider(){ loc = new PVector(random(width),random(height)); lastloc = new PVector(loc.x,loc.y); vel = new PVector(0,0); acc = new PVector(0,0); alpha = random(100); } void update(){ lastloc= loc.get(); flock(wlist,slist); vel.add(acc); vel.limit(maxspeed); loc.add(vel); acc.mult(0); borders(); } void drawSpider() { fill(0); ellipse(loc.x, loc.y,rad * 2, rad * 2); pushMatrix(); translate(loc.x,loc.y); rotate(vel.heading2D()+radians(90)); line(0,0,0,-10); popMatrix(); for (int j = 0; j < 2; j++) { ellipse(lastloc.x - random(-rad/4,rad/4),lastloc.y - random(-rad/4,rad/4),rad*2,rad*4); // image(mote3, lastloc.x - random(-rad/2, rad/2), lastloc.y - random(-rad/2, rad/2), rad * 2, rad * 2); }; strokeWeight(random(.5,1.5)); stroke(0,0,0,random(100,115)); for (int i = 0; i < 20; i++) { pushMatrix(); translate(loc.x, loc.y); rotate(tan(noise(alpha)*20)); line(0,0,0,noise(alpha)*20); popMatrix(); alpha += .001; }; } // We accumulate a new acceleration each time based on three rules void flock(ArrayList wlist, ArrayList slist) { PVector sep1 = separateBoids(slist); PVector sep = separateSlugs(wlist); // Separation PVector ali = align(slist); // Alignment PVector coh = cohesion(slist); // Cohesion // Arbitrarily weight these forces sep1.mult(20.0); sep.mult(70.0); ali.mult(1.0); coh.mult(1.0); // Add the force vectors to acceleration acc.add(sep1); acc.add(sep); acc.add(ali); acc.add(coh); // println(acc.x); } PVector separateBoids (ArrayList boids) { float desiredseparation = 25.0f; PVector sum = new PVector(0,0,0); int count = 0; // For every boid in the system, check if it's too close for (int i = 0 ; i < boids.size(); i++) { Spider other = (Spider) boids.get(i); float d = PVector.dist(loc,other.loc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from neighbor PVector diff = PVector.sub(loc,other.loc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } PVector separateSlugs (ArrayList slugs) { float desiredseparation = 80.0f; PVector sum = new PVector(0,0,0); int count = 0; // For every boid in the system, check if it's too close for (int i = 0 ; i < slugs.size(); i++) { Walker other = (Walker) slugs.get(i); float d = PVector.dist(loc,other.loc); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from neighbor PVector diff = PVector.sub(loc,other.loc); diff.normalize(); diff.div(d); // Weight by distance sum.add(diff); count++; // Keep track of how many } } // Average -- divide by how many if (count > 0) { sum.div((float)count); } return sum; } // Alignment // For every nearby boid in the system, calculate the average velocity PVector align (ArrayList boids) { float neighbordist = 100.0; PVector sum = new PVector(0,0,0); int count = 0; for (int i = 0 ; i < boids.size(); i++) { Spider other = (Spider) boids.get(i); float d = PVector.dist(loc,other.loc); if ((d > 0) && (d < neighbordist)) { sum.add(other.vel); count++; } } if (count > 0) { sum.div((float)count); sum.limit(maxforce); } return sum; } // Cohesion // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location PVector cohesion (ArrayList boids) { float mousedist = 200.0; PVector sum = new PVector(mouseX,mouseY,0); float d = PVector.dist(loc,sum); if ((d > 0) && (d < mousedist)) { return steer(sum,true); // Steer towards the location } else{ sum = new PVector(0,0,0); return sum; } } 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 < 200.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 borders() { if (loc.x < -rad) loc.x = width+rad; if (loc.y < -rad) loc.y = height+rad; if (loc.x > width+rad) loc.x = -rad; if (loc.y > height+rad) loc.y = -rad; } }