Function in C (and also in C++, Perl, Lisp, Python, ...) which computes the angle of the vector (x,y) with the x axis. To convert (x,y) to polar coordinates, you say

r = √(x2+y2)
θ = atan2(y,x)

atan2(y,x) ≠ atan(y/x) (!!)

To see why, it is sufficient to consider the cases x=y=1 and x=y=-1. In both cases, y/x=1, and atan(1)=π/4. But considering the direction we need to go from the x axis to get to (1,1) or to (-1,-1), we see that atan2(1,1)=π/4, while atan2(-1,-1)=5π/4 points in exactly the opposite direction.

Besides, when x=0 you really don't want to be dividing by x. And when |x| is very small compared to |y|, computing first y/x and then taking the arctangent is very inaccurate.

Indeed, the range of atan is [-π/2,π/2], whereas that of atan2 is [-π,π].

All these unpleasantries associated with the use of atan(x) conspire to make atan2(y,x) the more useful function, despite the fact you don't learn it in high school...

A function built into the numerical library of many programming languages, including C/C++, FORTRAN, etc, etc, etc. atan2 takes two floating-point parameters and returns a third in the range to π. The return values are usually interpreted to represent the "direction" of a two-dimensional vector where the two arguments represent the vector's scalar components. atan2 can also be used to determine the argument of a complex number or the angle Θ when converting from rectangular to polar coordinates.

The name "atan2" harks back to the days of numerical processing in FORTRAN. The people who built the function into FORTRAN probably called it ATAN2 to mean "two argument ATN". To me, ATAN2 is an awkward name; "Azimuth" would be a better name except that the latter name implies a different frame of reference in direction space.

Many programming languages also have at least one inverse trigonometric function, usually the inverse of the tangent function. This takes different names (atn, atan, arctan) in different languages, so we'll use the notation form mathematics (tan-1) in the rest of this writeup.

Spatial software is often concerned with determining "direction". Direction is usually measured by calculating an angle relative to a reference direction. Inverse trigonometric functions are used to calculate angles, because the traditional geometric interpretation of a trig function as a value derived from an angle leads to a reasonable interpretation of the inverse function as an angle derived from a number.

Return values from tan-1 can also be interpreted to mean a "direction". Unfortunately, "direction" means different things in different circumstances, and circumstances often dictate that these "directions" are not the "directions" we want.

If we're talking about the "direction" of a line segment, and if we don’t care which end of the segment is "first", then "direction" simply means the segment's orientation in space; and something calculated from tan-1 may be sufficient.

But what if we want the "direction" of travel down a road? If we use return values from tan-1 we cannot tell southwest (tan -3π/4=1) from northeast (tan π/4=1). tan-11 = π/4 and we have to interpret it as "either southwest OR northeast". We can't tell which.

Why is this the case? Well, in order for a relation between numbers to be considered a function (in the mathematical sense) there has to be a single value in the codomain associated with each value in the domain (the codomain of a function is called its range).

Let's consider tan-10. x=tan-1 0 means tan x = 0. But tan πj = 0 for every integer j. An implementation of tan-1 has to choose exactly one of the infinite possible values to be considered a "function". All inverse trigonometric functions have this problem, and mathematicians get around it by choosing a range of values to return. It's conventional to choose j=0. Since


Lima→π/2 tan a = ∞
Lim-π/2←a tan a = -∞

we can define


tan-1 -∞ = -π/2
tan-1 ∞ = π/2

designing an implementation of tan-1 to range from -π/2 to π/2 with the domain from -∞ to . This is the range that atn() or what have you usually takes.

If you don't need to tell the difference between southwest and northeast (called "sense"), this is sufficient to describe a direction.

But if you do care which end of the segment is first, tan-1 isn't enough. Interpreting the line segment as a vector, "direction" now means the combination of the vector's orientation and sense. In order to have a function that returns all direction values (which range from to π), more information than just one number is required: the signs of both components of the vector must be considered. Thus, a "two argument inverse tangent".

The notion of an azimuth, which came from navigation and surveying, also fully describes a vector's direction; however, azimuths are traditionally measured in degrees, use due north as a reference angle (i.e. the value associated with 0) and values run to 360° (i.e. 2π) as directions rotate clockwise. atan2 is measured in radians, uses due east as a reference angle, and values increase as directions rotate counterclockwise. ±pi represents due west. atan2's interpretation is preferable since it is consistent with the geometrical representation of trig functions as projections onto the x and y axes.


Here is my implementation of atan2 in Pascal, a language I have a special fondness for, and which doesn't have an atan2 built in by default:

function atan2 (dy: real; dx: real): real;

const pi = 3.14159265359;
const half_pi = pi / 2;

var a: real;

begin { atan2 }
{
 use arctan, avoiding division by zero.
}
if abs (dx) > abs (dy)
   then a := arctan (dy/dx)
   else begin
        a := arctan (dx/dy); { pi/4 <= a <= pi/4 }
        if a < 0
           then a := -half_pi-a  { a is negative, so we're adding }
           else a := half_pi-a
        end;
if dx < 0
   then if dy < 0
           then a := a - pi
           else a := a + pi;
atan2 := a
end;  { atan2 }

Log in or register to write something here or to contact authors.