Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // The Nature of Code
- // Daniel Shiffman
- // http://natureofcode.com
- // Demonstration of Craig Reynolds' "Flocking" behavior
- // See: http://www.red3d.com/cwr/
- // Rules: Cohesion, Separation, Alignment
- // Click mouse to add boids into the system
- // video stuff added by Jerome Herr
- import processing.video.*;
- import com.hamoid.*;
- VideoExport videoExport;
- Movie movie;
- Flock flock;
- void setup() {
- size(1280, 720);
- background(238);
- //frameRate(30);
- movie = new Movie(this, "beyonce.mp4");
- movie.play();
- flock = new Flock();
- // Add an initial set of boids into the system
- for (int i = 0; i < 350; i++) {
- Boid b = new Boid(width/2, height/2);
- flock.addBoid(b);
- }
- videoExport = new VideoExport(this, "internetVideo" + random(9999) + ".mp4");
- //videoExport.setFrameRate(30);
- videoExport.startMovie();
- }
- void draw() {
- //background(255);
- flock.run();
- videoExport.saveFrame();
- // Instructions
- //fill(0);
- //text("Drag the mouse to generate new boids.", 10, height-16);
- }
- // Add a new boid into the System
- void mouseDragged() {
- //flock.addBoid(new Boid(mouseX, mouseY));
- }
- void movieEvent(Movie movie) {
- movie.read();
- }
- void mouseReleased() {
- //save(random(99999)+".png");
- }
- void keyPressed() {
- if (key == 'q') {
- videoExport.endMovie();
- //exit();
- }
- }
- // The Nature of Code
- // Daniel Shiffman
- // http://natureofcode.com
- // Boid class
- // Methods for Separation, Cohesion, Alignment added
- class Boid {
- PVector position;
- PVector velocity;
- PVector acceleration;
- float r;
- float maxforce; // Maximum steering force
- float maxspeed; // Maximum speed
- int sz;
- Boid(float x, float y) {
- acceleration = new PVector(0, 0);
- velocity = new PVector(random(-1, 1), random(-1, 1));
- position = new PVector(x, y);
- r = 3.0;
- maxspeed = 3;
- maxforce = 0.05;
- }
- 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 position
- void update() {
- // Update velocity
- velocity.add(acceleration);
- // Limit speed
- velocity.limit(maxspeed);
- position.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, position); // A vector pointing from the position to the target
- // Normalize desired and scale to maximum speed
- desired.normalize();
- desired.mult(maxspeed);
- // Steering = Desired minus Velocity
- PVector steer = PVector.sub(desired, velocity);
- steer.limit(maxforce); // Limit to maximum steering force
- return steer;
- }
- void render() {
- sz = (int) random(20, 50);
- PImage tmp = movie.get(int(position.x), int(position.y), sz, sz);
- tint(255, 100);
- image(tmp, position.x, position.y);
- }
- void render_old() {
- // Draw a triangle rotated in the direction of velocity
- float theta = velocity.heading2D() + radians(90);
- fill(175);
- stroke(0);
- pushMatrix();
- translate(position.x, position.y);
- rotate(theta);
- beginShape(TRIANGLES);
- vertex(0, -r*2);
- vertex(-r, r*2);
- vertex(r, r*2);
- endShape();
- popMatrix();
- }
- // Wraparound
- void borders() {
- if (position.x < -r) position.x = width+r;
- if (position.y < -r) position.y = height+r;
- if (position.x > width+r) position.x = -r;
- if (position.y > height+r) position.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(position, other.position);
- // 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(position, other.position);
- 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) {
- // 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(position, other.position);
- if ((d > 0) && (d < neighbordist)) {
- sum.add(other.velocity);
- count++;
- }
- }
- if (count > 0) {
- sum.div((float)count);
- 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 position (i.e. center) of all nearby boids, calculate steering vector towards that position
- PVector cohesion (ArrayList<Boid> boids) {
- float neighbordist = 50;
- PVector sum = new PVector(0, 0); // Start with empty vector to accumulate all positions
- int count = 0;
- for (Boid other : boids) {
- float d = PVector.dist(position, other.position);
- if ((d > 0) && (d < neighbordist)) {
- sum.add(other.position); // Add position
- count++;
- }
- }
- if (count > 0) {
- sum.div(count);
- return seek(sum); // Steer towards the position
- } else {
- return new PVector(0, 0);
- }
- }
- }
- // The Nature of Code
- // Daniel Shiffman
- // http://natureofcode.com
- // Flock class
- // Does very little, simply manages the ArrayList of all the boids
- 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
- }
- }
- void addBoid(Boid b) {
- boids.add(b);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement