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. Let’s create the flocking algorithm.

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

What is the flocking algorithm

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:

Our bird moving across the screen

Perfect, now let’s add him some friends:

Our bird with lots of other birds

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:

Our bird with little halos to depict their vision

And then I measure the distance between the birdies:

Our bird detecting other birds

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;
  }
The birds interacting with eachother

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;
  }
Separation at play

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:

Them working together

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;
  }
Alignment at play

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.

Editing the settings!

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