Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Note: If there is 150 node, you need at least 150 boids
- //But you can put more boids in the screen than the number of nodes
- Flock flock;
- int nbBoid = 300;
- Node[] nodes = new Node[nbBoid];
- int nodeCount = 150;
- void setup() {
- size(1000, 1000, P2D);
- flock = new Flock();
- // Add an initial set of boids into the system
- for (int i = 0; i < nbBoid; i++) {
- //flock.addBoid(new Boid(random(width), random(height)));
- flock.addBoid(new Boid(random(width), random(height)));
- nodes[i] = new Node(i, nodes);
- }
- }
- void draw() {
- background(0);
- fill(0);
- rect(0, 0, width, height);
- flock.run();
- for (int i = 0; i < nbBoid; i++) {
- //Set the postition of the node at the position of the boid
- nodes[i].setPos(flock.getPos(i));
- }
- for (int i = 0; i < nbBoid; i++) {
- nodes[i].display();
- nodes[i].displayNetwork(nodeCount);
- }
- //saveFrame("output/img####.tif");
- }
- // The Flock (a list of Boid objects) Note: By Daniel Shiffman
- //I took the example from the website Processing.org
- class Flock {
- ArrayList<Boid> boids; // An ArrayList for all the boids
- Flock() {
- boids = new ArrayList<Boid>(); // Initialize the ArrayList
- }
- void run() {
- for (Boid b : boids) {
- b.run(boids); // Passing the entire list of boids to each boid individually
- }
- }
- PVector getPos(int _i) {
- return boids.get(_i).getPos();
- }
- void addBoid(Boid b) {
- boids.add(b);
- }
- }
- // The Boid class
- class Boid {
- PVector location;
- PVector velocity;
- PVector acceleration;
- float r;
- float maxforce; // Maximum steering force
- float maxspeed; // Maximum speed
- Boid(float x, float y) {
- acceleration = new PVector(0, 0);
- // This is a new PVector method not yet implemented in JS
- // velocity = PVector.random2D();
- // Leaving the code temporarily this way so that this example runs in JS
- float angle = random(TWO_PI);
- velocity = new PVector(cos(angle), sin(angle));
- location = new PVector(x, y);
- r = 2.0;
- maxspeed = 2;
- maxforce = 0.03;
- }
- PVector getPos() {
- return location;
- }
- void run(ArrayList<Boid> boids) {
- flock(boids);
- update();
- borders();
- //render();
- }
- void applyForce(PVector force) {
- // We could add mass here if we want A = F / M
- acceleration.add(force);
- }
- // We accumulate a new acceleration each time based on three rules
- void flock(ArrayList<Boid> boids) {
- PVector sep = separate(boids); // Separation
- PVector ali = align(boids); // Alignment
- PVector coh = cohesion(boids); // Cohesion
- // Arbitrarily weight these forces
- sep.mult(1.5);
- ali.mult(1.0);
- coh.mult(1.0);
- // Add the force vectors to acceleration
- applyForce(sep);
- applyForce(ali);
- applyForce(coh);
- }
- // Method to update location
- void update() {
- // Update velocity
- velocity.add(acceleration);
- // Limit speed
- velocity.limit(maxspeed);
- location.add(velocity);
- // Reset accelertion to 0 each cycle
- acceleration.mult(0);
- }
- // A method that calculates and applies a steering force towards a target
- // STEER = DESIRED MINUS VELOCITY
- PVector seek(PVector target) {
- PVector desired = PVector.sub(target, location); // A vector pointing from the location to the target
- // Scale to maximum speed
- desired.normalize();
- desired.mult(maxspeed);
- // Above two lines of code below could be condensed with new PVector setMag() method
- // Not using this method until Processing.js catches up
- // desired.setMag(maxspeed);
- // Steering = Desired minus Velocity
- PVector steer = PVector.sub(desired, velocity);
- steer.limit(maxforce); // Limit to maximum steering force
- return steer;
- }
- void render() {
- // Draw a triangle rotated in the direction of velocity
- float theta = velocity.heading2D() + radians(90);
- // heading2D() above is now heading() but leaving old syntax until Processing.js catches up
- fill(200, 100);
- stroke(255);
- pushMatrix();
- translate(location.x, location.y);
- rotate(theta);
- beginShape(TRIANGLES);
- vertex(0, -r*2);
- vertex(-r, r*2);
- vertex(r, r*2);
- endShape();
- popMatrix();
- }
- // Wraparound
- void borders() {
- if (location.x < -r) location.x = width+r;
- if (location.y < -r) location.y = height+r;
- if (location.x > width+r) location.x = -r;
- if (location.y > height+r) location.y = -r;
- }
- // Separation
- // Method checks for nearby boids and steers away
- PVector separate (ArrayList<Boid> boids) {
- float desiredseparation = 25.0f;
- PVector steer = new PVector(0, 0, 0);
- int count = 0;
- // For every boid in the system, check if it's too close
- for (Boid other : boids) {
- float d = PVector.dist(location, other.location);
- // 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(location, other.location);
- diff.normalize();
- diff.div(d); // Weight by distance
- steer.add(diff);
- count++; // Keep track of how many
- }
- }
- // Average -- divide by how many
- if (count > 0) {
- steer.div((float)count);
- }
- // As long as the vector is greater than 0
- if (steer.mag() > 0) {
- // First two lines of code below could be condensed with new PVector setMag() method
- // Not using this method until Processing.js catches up
- // steer.setMag(maxspeed);
- // Implement Reynolds: Steering = Desired - Velocity
- steer.normalize();
- steer.mult(maxspeed);
- steer.sub(velocity);
- steer.limit(maxforce);
- }
- return steer;
- }
- // Alignment
- // For every nearby boid in the system, calculate the average velocity
- PVector align (ArrayList<Boid> boids) {
- float neighbordist = 50;
- PVector sum = new PVector(0, 0);
- int count = 0;
- for (Boid other : boids) {
- float d = PVector.dist(location, other.location);
- if ((d > 0) && (d < neighbordist)) {
- sum.add(other.velocity);
- count++;
- }
- }
- if (count > 0) {
- sum.div((float)count);
- // First two lines of code below could be condensed with new PVector setMag() method
- // Not using this method until Processing.js catches up
- // sum.setMag(maxspeed);
- // Implement Reynolds: Steering = Desired - Velocity
- sum.normalize();
- sum.mult(maxspeed);
- PVector steer = PVector.sub(sum, velocity);
- steer.limit(maxforce);
- return steer;
- } else {
- return new PVector(0, 0);
- }
- }
- // Cohesion
- // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
- PVector cohesion (ArrayList<Boid> boids) {
- float neighbordist = 50;
- PVector sum = new PVector(0, 0); // Start with empty vector to accumulate all locations
- int count = 0;
- for (Boid other : boids) {
- float d = PVector.dist(location, other.location);
- if ((d > 0) && (d < neighbordist)) {
- sum.add(other.location); // Add location
- count++;
- }
- }
- if (count > 0) {
- sum.div(count);
- return seek(sum); // Steer towards the location
- } else {
- return new PVector(0, 0);
- }
- }
- }
- ///////////////////////////////////////////////////////////
- //It might be an example from Casey Reas / ben Fry's book, Processing for visual designer
- class Node {
- PVector pos = new PVector(0, 0);
- float radius = 20;
- color col = 0;
- int ID;
- float r;
- Node[] otherNodes;
- Node(int _ID, Node[] _otherNodes) {
- otherNodes = _otherNodes;
- ID = _ID;
- }
- void setPos(PVector _pos) {
- pos = _pos.copy();
- col = color(map(pos.x + pos.y, 0, width+height, 255, 0), map(pos.x + pos.y, 0, width+height, 127, 255), map(pos.x * pos.y, 0, width*height, 0, 255));
- }
- void display() {
- ellipseMode(RADIUS);
- noStroke();
- r = (sin(frameCount*0.1)+2+noise(ID*150)*10);
- fill(col, map(r, 8.0, 20.0, 30, 200));
- ellipse(pos.x, pos.y, r, r);
- }
- void displayNetwork(int _nodeCount) {
- for (int i = ID+1; i < _nodeCount; i++) {
- if (overlap(otherNodes[i])) {
- beginShape(LINES);
- strokeWeight(sin(frameCount*0.1+PI)+2+noise(ID*150));
- stroke(col, map(r, 8.0, 20.0, 30, 200));
- vertex(pos.x, pos.y);
- stroke(otherNodes[i].col);
- vertex(otherNodes[i].pos.x, otherNodes[i].pos.y);
- endShape();
- }
- }
- }
- boolean overlap(Node n) {
- float _dist = dist(pos.x, pos.y, n.pos.x, n.pos.y);
- float diameter = radius + n.radius;
- if (_dist < diameter) {
- return true;
- } else {
- return false;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement