Flock: Maths through example

Until a better name approaches the recesses of my mind, Flock is my newest flocking simulator, building off an old simulator which I made two videos on.

Rather than go with Java, which was my language of choice two years ago, I decided to try and learn a bit of HTML 5 and JavaScript and render it in-browser this time, as opposed to fiddling with AWT.

I've also managed to reduce down the maths to a more manageable amount; oh an for the record acos2 is awesome.

So what maths is there, well you remember arguing that you'd never need to know the length of a side of a triangle based on the angle and another length: it's that sort of maths. As know as trigonometry, or trig if you're being lazy.

There's really two different things which need to be worked out for the basic movement of the "birds": working out a heading, limited by a certain turning angle; and calculating the opposite and adjacent knowing a heading and a hypotenuse.

First of let's go back to basics, a right angled triangle:

Best triangle ever

Okay, it's not the best triangle you've ever seen, but that little square means it really is right angled, even if it looks like it isn't.

Some clever fellow (Pythagoras) worked out that the hypotenuse (which is just a fancy word for the longest side) which is a in that picture has a length related to the other two sides:

Dr Pythagoras in the house

Actually, as a programmer, you can generally get away with being lazy and never take the square root as Pythagoras' theory is normally used to check distances: its easier just to square the other length than it is to take the computation of a square root.

Now we get into proper trig; in trig we focus on an angle (that isn't the square root, that would be far too easy). The angle we call θ (theta). a remains the hypotenuse, b and c get called something else, depending where θ is.

If we leave θ where it is, b is the opposite and c is the adjacent.

θ, a, b and c are all related, for example:

  • sin θ = b ÷ a
  • cos θ = c ÷ a
  • tan θ = b ÷ c

So in programming terms we usually either want to work out θ using b and c, or b and c knowing θ and a.

Why? Well lets take an example:

We start at a point (x, y) and we want to move a certain distance at a given heading. Well the distance is the hypotenuse and the heading is θ. From there we need to work out the other two sides of the triangle to work out where to move to.

As always a picture tells a thousand words:

Moving from one place to another

To help I've pulled out some things in different colours. Red is our starting point and where we want to move it to. We add blue to get an angle θ. 0 is placed somewhat arbitrarily here, but up is most natural for us humans to think of.

In green we have the really important bits, what we want to work out.

Black just adds some information for the upcoming equation:

Working out where to move to

Our new co-ordinate uses the relations described about, but just rearranged slightly: b = cos θ × a and c = sin θ × a. From these we just add on our existing location and like that, we have our new location.

Of course this is all well and good if we know a heading. The flocking simulator works on calculating an aim depending on the proximity of neighbours to a bird. The distance travelled is the based of the speed of the bird and is currently restricted to 1.

Here we work opposite to what we just did. We know both sets of x and y, and it's θ which is the thing to calculate.

Back to the relations, the one we want here is: tan θ = b ÷ c; but this time its a bit more difficult to rearrange this as θ = ??? b ÷ c, where ??? is the inverse of tan.

This is known as arctan; and we could use θ = arctan (b ÷ c), but most programming languages provide a nicer implementation: arctan2(b, c), which does the same thing.

Then it's just a simple(!) case of only allowing a certain amount of turn in the calculation of a new angle then it's all downhill from there.