Monday, 30 January 2012

Inverse trigonometry

The functions asin, acos and atan are together the three principal inverse trigonometric functions; that is they are the inverse of the sine, cosine and tangent functions, the commonest trigonometric functions that describe all the ratios of the sides of a right-angled triangle.

For example, consider the above diagram (source: Wikipedia), with the angle is at the lower-left corner labelled A. Then sin(A) = a / c, cos(A) = b / c and tan(A) = a / b. This means given two of the sides the angle can be calculated, using one of the following: A = asin (a / c) = acos ( b / c) = atan (a / b).

But this does not generalise well. Consider instead a point in two dimensions, at (x, y), and a distance r from the origin, so r2 = x2 + y2, from Pythagoras's theorem. But unlike the triangle x and y do not have to be positive numbers, they can be zero or negative.

This leads to immediate problems for calculating the angle, now the bearing of the point from the origin. For example using atan fails when x is zero as dividing by zero gives an error. The problems with asin and acos are more subtle but are therefore harder to deal with: both become increasingly inaccurate when the fraction in their calculation approaches 1, when the sides being used get closer to being the same.

And all three suffer from additional problems. For example consider the point (1, 1). The formula for the bearing is atan (y / x), which gives atan(1) which is π / 4 or 45°. But the point (-1, -1) gives the same result. So the function calculates the same bearing for two points that are on opposite sides of the origin. The trigonometric function tan has period, or repeats, every π or 180°, so atan cannot tell apart two points that are separated by that angle.

Thankfully these problems can be avoided, and it is the function atan2. This takes two numbers, the y and x coordinates of a point (no need to divide them) and returns the angle. It avoids all the problems of the 'traditional' inverse trigonometric functions, and so is almost always better for calculating the bearing.

In Flash it is part of the Math class, as Math.atan2. It can be found in most programming languages, added so programs and programmers can avoid the issues of asin, acos and atan (which are also in the Math class but are best left alone unless they are called on for particular algorithms or calculations).