Friday, 6 January 2012


Recent posts have focussed on how to avoid angles when programming. The reason for this is simple: angles are slow to work with. In particular the trigonometric functions used to work with angles are expensive compared to arithmetic operations. There are times though when it is impossible to avoid angles.

The most obvious instance is converting circular motion to linear motion. Example include a rack and pinion gear, parts of a belt drive, or any wheel moving on a flat surface or rail. In theory such motions, being governed by Newton's laws and kinematics, can be calculated without angles. But in practice they are best described with angles.

Another case where angles are needed is dividing a rotation. Rotations, stored as complex numbers, are combined by multiplying the complex numbers representing the rotations. To apply a rotation multiple times it is raised to a power. E.g. if a rotation is represented by complex number z then zn is the rotation applied n times. So to subdivide a rotation, so to find the rotation which applied n times gives the desired rotation, involves taking roots.

And for complex numbers finding the nth root requires trigonometry. In particular it is an application of de Moivre's formula, which relates angles, trigonometry and powers of complex numbers. This is demonstrated in my ballistics app, in the AimGun function, when it does this

    var fStep:Number = (fAngle2 - fAngle1) / 30;
    rStep = Math.cos(fStep);
    iStep = Math.sin(fStep);

It is in effect calculating z = cos (t / 30) + i sin (t / 30) = [cos (t) + i sin (t)]1/30, so deriving the rotation which when applied 30 times over a second rotates through the desired angle (which must be calculated first).

The one exception to the above is 'halving' a rotation, which can be done without trigonometry using the square root of a complex number, a process which can be repeated to generate fourth, eighth and higher roots. This though is at least as complex as the trigonometric approach, so is of mostly theoretical interest.

It is also easier in my app to use the angle to calculate the time taken to rotate at a fixed sped. It would be possible and is quite straightforward to do this without angles, by e.g. comparing the direction to the desired direction and stopping when they are close enough. But it is even easier to do this by comparing the time taken to a pre-calculated duration, a calculation which involves angles but is only done once.

A final use for angles is communicating with users, as more people understand angles than complex numbers (or some other way of representing rotations). This applies to displaying angles, as seen in my ballistics app. It applies even more to inputting angles, in an editor, or manipulating them directly in a visual editor.

Overall it is important to know when angles can be replaced by faster often simpler mathematics. But it is as important to know when angles are unavoidable, or at least are far preferable, so no time is wasted looking for optimisations which aren't there.

No comments:

Post a comment