A 3D Flocking Simulation using HTML5 Canvas

Alex Cruikshank ·

Birds on a Power Line applicationI recently unearthed an old Java applet that I had written many years ago and decided to see what it would look like as a single page canvas application (an HTML5 compatible browser is required to view this page). The applet was inspired by the way blackbirds roost on power lines in San Francisco (and probably everywhere else).  I started with something close to Craig Reynold’s classic Boids algorithm, which is remarkable for generating motion resembling a flock of birds by giving each particle only 3 relatively simple mathematical constraints.  I had to add 6 more rules to incorporate the power line behavior (2 for landing, 1 for hopping on the line, and 3 for launching off the line).

The rules are:

  1. A flying bird is attracted to the average location of all nearby birds.
  2. The velocity of a flying bird will tend towards the average velocity of its neighbors.
  3. A bird will fly in the opposite direction of any object (another bird or a wall) that is too close.
  4. A flying bird within a certain distance of a power line will slow down.
  5. A flying bird within an even smaller distance of a power line and flying a low velocity will land.
  6. A sitting bird will make a series of discrete steps to either reach a comfortable distance from a neighboring bird or to equalize the distance between two birds.
  7. A sitting bird trapped at an unacceptable distance between two birds will launch.
  8. A sitting bird will launch if the average velocity of nearby flying birds meets a certain threshold.
  9. A sitting bird will launch if a flying bird approaches too closely.

Since the application is only required to draw simple circles and lines, there was little opportunity to explore features of the canvas API.  Most of the code is devoted to the calculations.  JavaScript isn’t great at handling all the vector math.  I tried to write it in a more functional style, but the additional object creation and function calls required to do immutable math turned out to make a pretty significant increase in CPU usage, so I replaced some each calls with for loops and tried to minimize the need to generate 3D point objects.  I could have eliminated the points altogether and run the calculations on each coordinate separately, but the performance boost wouldn’t be worth the mess it would make in the code.

Feel free to view the source and use what you like.  I’ve been doing a lot of canvas work that I’ll be posting about here soon.

Alex Cruikshank
Alex Cruikshank

Alex is Carbon Five's resident mad genius. He is recently very involved in functional languages, and has been anchoring teams at C5 for the past decade.