• fullscreen
  • Dot.pde
  • flock_demo_op.pde
  • class Dot{ // define a new class
    
      float diameter;
      color c;
    
      PVector pos; // position
      PVector vel; // velocity
      PVector acc; // acceleration
    
      float mouseFactor = 0.1; // strength of mouse attraction
    
      // cohesion variables
      float cohesionFactor = 0.2;
      float cohesionRadius =  40;
    
      // alignment variables
      float alignFactor = 0.1;
      float alignRadius =  40;
    
      // separation variables
      float separationFactor = 1.5;
      float separationRadius =  25;
    
      // speed limit
      float maxVel = 5;
      
      // friction
      float frictionFactor = 0.95;
    
    
      Dot(PVector _pos, float _diameter){ // constructor function has same name as class
        // constructor gets called when we make a new Dot
        pos = _pos;
        diameter = _diameter;
        vel = new PVector(random(-5,5),random(-5,5),0); // random initial velocity
        c = color(random(100,255),random(100,255),random(100,255)); // random initial colour
        acc = new PVector(0,0,0); // set acceleration to 0
      }
    
      void run(){ // the main function - calls all the other behaviours and updates position and acceleration
    
          steerMouse(); // steer to mouse factor
        bounce(); 
        cohesion(); // cohesion factor, radius
        separation(); // separation factor, radius
        alignment();
        friction();
        speedLimit();
    
        render();
    
        vel.add(acc); // update the velocity vector - add the current acceleration vector 
        pos.add(vel); // update the position - add the current velocity vector
        acc.mult(0); // reset acceleration to 0
    
      }
    
      void render(){ // draw the dot
        fill(c);
        ellipse(pos.x,pos.y,diameter,diameter);
      }
    
    
    
      void bounce(){
        if (pos.x > width || pos.x < 0){ // if x pos is greater than right hand edge OR less than left hand edge
          vel.set(vel.x*-1,vel.y,0); // bounce off the edge
        }
        if (pos.y > height || pos.y < 0) { // if y pos is greater than bottom edge OR less than top edge
          vel.set(vel.x,vel.y*-1,0);
        }
    
      }
    
      void steerMouse(){
        PVector mousePos = new PVector (mouseX,mouseY,0); // make a new vector based on the mouse position
        PVector toMouse = PVector.sub(mousePos,pos); // make a vector that point towards the mouse by subtracting vectors
        toMouse.normalize(); // scales the magnitude of the vector to 1
        toMouse.mult(mouseFactor); // multiplies the vector by the mouseFactor argument - which defines the strength of the mouse influence
        acc.add(toMouse); // add the toMouse force to our current acceleration
      }
    
      void separation(){
        for (int i=0; i<Dots.size(); i++){ // run through the arraylist
          Dot Neighbour = (Dot) Dots.get(i); // get each Dot
          float distance = PVector.dist(pos,Neighbour.pos); 
          if (distance < separationRadius){ // if this Dot is within our separation range then
            PVector toNeighbour = PVector.sub(pos,Neighbour.pos); // make a vector from the neighbour
            toNeighbour.normalize(); // scale it to 1
            // now scale it according to distance, so that it's strong at close range, and reduces to 0 at the separation radius
            // then multiply it by the separationFactor, which allows us to control the overal strength of the separation force
            toNeighbour.mult(((separationRadius-distance)/separationRadius)*separationFactor); 
            acc.add(toNeighbour); // add the separation force to the acceleration
          }
        }
      }
    
      void cohesion(){ // each agent steers towards the average position of its neighbours
        PVector avePos = new PVector(); // PVector to store average position
        int neighbourcount = 0; // int to count the number of neighbours
        for (int i=0; i<Dots.size(); i++){
          Dot Neighbour = (Dot) Dots.get(i);
          float distance = PVector.dist(pos,Neighbour.pos);
          if (distance < cohesionRadius){
            avePos.add(Neighbour.pos);
            neighbourcount++;
          }
        }
        avePos.div(neighbourcount); // divide by num neighbours to get the average - the center position of our near neighbours
        PVector toCenter = PVector.sub(avePos,pos); // make a vector to that point
        toCenter.normalize(); // scale it to 1
        toCenter.mult(cohesionFactor); // multiply by cohesion factor
        acc.add(toCenter);    // add the cohesion force to the acceleration
      }
    
    
      void alignment(){
        PVector aveVel = new PVector(); // PVector to store average velocity of our neighbours
        for (int i=0; i<Dots.size(); i++){
          Dot Neighbour = (Dot) Dots.get(i);
          float distance = PVector.dist(pos,Neighbour.pos);
          if (distance < alignRadius){ // if the dot is within our alignment range
            aveVel.add(Neighbour.vel); // add its velocity to the average
          }
        }
        aveVel.normalize(); 
        aveVel.mult(alignFactor);
        acc.add(aveVel);   
      }
    
    
      void speedLimit(){
        if (vel.mag() > maxVel){ // if you're going faster than the speed limit
          vel.normalize(vel).mult(maxVel); // scale your velocity back to the limit
        }
      }
    
      void friction(){
        vel.mult(frictionFactor); // multiply velocity by the friction factor
      }
    
    }
    
    
    
    
    
    // flock demo
    // mitchell whitelaw
    // demo code for introduction to digital design, master of digital design program, university of canberra 
    
    ArrayList Dots = new ArrayList(); // make an empty arraylist
    int numDots = 10; // number of dots created per click
    
    void setup(){
      size(500,500);
      background(0);
      noStroke();
      smooth();
    }
    
    void draw(){
      background(0);
      for (int i=0; i<Dots.size(); i++){ // step through the arraylist - size() gets the size of the arraylist
        Dot tempD = (Dot) Dots.get(i); // get an object out of the list, put it in tempD
        tempD.run(); //  call the object's run function
      }
    }
    
    void mousePressed(){
      for (int i=0; i<numDots; i++){ // make a bunch of new Dots
        Dot D = new Dot(new PVector(mouseX,mouseY,0),random(10,20)); // make new Dot at mouse pos, with diameter between 10 and 20
        Dots.add(D); // add D to the arraylist Dots
      }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    mitchell whitelaw
    Cedric Kiefer
    5 Nov 2009
    I really like it. I was playing arround with it, and was wondering what i have to change to make them move much slower but still get the flocking behavior. If you just change, the friction or velocity, they stick close to each other... how does it work?
    You need to login/register to comment.