The Flocking Algorithm

This week I thought I’d have a bit of a play with creating a simulation – I love the idea of creating a whole new universe with just my fingers, some coffee and a good attitude.

I’ve already created an infinite procedurally generated universe so creating a simulation is right up my street.

What is the flocking

Flocking is a behaviour that a group of birds exhibit, the flocking algorithm is just an attempt at recreating this behaviour with 3 very simple rules: separation, alignment and cohesion. In this blog I’m going to be taking a crack at implementing this using JavaScript and the p5.js library.

Getting started

All of the code that I’m about to write can be found here so feel free to have a play yourself!

First step is to create a Bird, to start with I’m just going to make it very simple and have the Bird as a circle, moving in a random direction at a random speed:

Perfect, now let’s add him some friends:

Cohesion

Coherence means that Birds alter their position so that it corresponds with the average alignment of other nearby birds. Meaning we take the position of the birds that are within a certain radius of us and steer towards that.

I need some way to measure the distance between each bird, to do this I created a radius that’ll represent its vision:

And then I measure the distance between the birdies:

Now let’s implement the cohesion. To do this I add up all the vectors that represent the close Birds’ positions and then divide by the number of birds, this give us the centre location:

  coherence() {
    let closeBirdCount = 0;
    let sum = createVector(0, 0);
    for (let bird of birds) {
      if (bird !== this) {
        if (dist(this.pos.x, this.pos.y, bird.pos.x, bird.pos.y) < this.seeRadius) {
          closeBirdCount++;
          sum.add(bird.pos);
        }
      }
    }
    if (sum > 0) {
      sum.div(count);
    } 
    return sum;
  }

Notice how the birds are now attracted to each other! wonderful.

Separation

Separation basically means the Birds try not to bump into each other. So I need to look for Birds that are close and steer in a direction that moves me away from the other Birds.

  seperation() {
    let c = createVector(0, 0);
    let count = 0;
    for (let bird of birds) {
      if (bird !== this) {
        if (dist(this.pos.x, this.pos.y, bird.pos.x, bird.pos.y) < this.seeRadius) {
          count++;
          let difference = p5.Vector.sub(this.pos, bird.pos);
          c = p5.Vector.sub(difference, c);
        }
      }
    }
    return c;
  }

Well we’re definitely avoiding each other, but obviously that is a little bit too rigid. Let’s loosen up the rules a bit – putting a limit to the force applied:

Now the Birds flock together whilst trying to not bump into each other, how civil.

Alignment

Each Bird tries to keep a reasonable distance between itself and any nearby birds, to prevent overcrowding. To do this we calculate the sum of the velocity of nearby birds and then divide by the count to get the average velocity.

  align() {
    let sum = createVector(0, 0);
    let alignRadius = 50;
    let count = 0;
    for (let bird of birds) {
      if (bird !== this) {
         count++;
         if (dist(this.pos.x, this.pos.y, bird.pos.x, bird.pos.y) < alignRadius) {
           sum.add(bird.velocity);
         }
      }
    }
    if (count > 0) {
      sum.div(count);
    }
    return sum;
  }

And there we have it, that’s our flocking simulation!

And that’s pretty much flocking in a nutshell. If you go to the project I created you can play with different separations/alignment/cohesion settings. I’ve added a couple sliders to do the trick.

I hope you’ve enjoyed this blog, and if you have please sign up to my newsletter, I send out unique content every week to subscribers – it’s completely free.

Leave a Reply