Python atan or atan2, what should I use?
As others said, the atan2 takes two arguments to be able to determine the quadrant of the output angle properly...
However, it still outputs an angle between [-pi,pi]
, which is not always useful (positive [0,pi]
for 1st and 2nd quadrants; and negative [-pi,0]
for 3rd and 4th).
It's possible to define an atan
function that returns an angle in [0,2pi]
, as theodore panagos showed.
Improving on theodore panagos' answer, here is a python version using numpy
import numpy
# defining the atan function
myatan = lambda x,y: numpy.pi*(1.0-0.5*(1+numpy.sign(x))*(1-numpy.sign(y**2))\
-0.25*(2+numpy.sign(x))*numpy.sign(y))\
-numpy.sign(x*y)*numpy.arctan((numpy.abs(x)-numpy.abs(y))/(numpy.abs(x)+numpy.abs(y)))
#testing
u = numpy.array([[numpy.sqrt(3.0)/2.0,0.5], # expected: 30
[0.5,numpy.sqrt(3.0)/2.0], # expected: 60
[0.0,1.0], # expected: 90
[-0.5,numpy.sqrt(3.0)/2.0], # expected: 120
[-numpy.sqrt(3.0)/2.0,0.5], # expected: 150
[-1.0,0.0], # expected: 180
[-numpy.sqrt(3.0)/2.0,-0.5], # expected: 210
[-0.5,-numpy.sqrt(3.0)/2.0], # expected: 240
[0.0,-1.0], # expected: 270
[0.5,-numpy.sqrt(3.0)/2.0], # expected: 300
[numpy.sqrt(3.0)/2.0,-0.5], # expected: 330
[1.0,0.0]]) # expected: 0 or 360
theta = myatan(u[:,0],u[:,1])
print(theta * 180.0/numpy.pi) # converting to degrees
output:
[ 30. 60. 90. 120. 150. 180. 210. 240. 270. 300. 330. 0.]
it does not output 360 exactly, but it goes through up to it, then it cycles, as expected
Atan takes single argument and Atan2 takes two arguments.The purpose of using two arguments instead of one is to gather information on the signs of the inputs in order to return the appropriate quadrant of the computed angle, which is not possible for the single-argument Atan
Atan2 result is always between -pi and pi.
Reference: https://en.wikipedia.org/wiki/Atan2
docstring for math.atan:
atan(x) Return the arc tangent (measured in radians) of x.
docstring for math.atan2:
atan2(y, x) Return the arc tangent (measured in radians) of y/x. Unlike atan(y/x), the signs of both x and y are considered.
To be very complete, here's what the doc says about atan2:
math.atan2(y, x) Return atan(y / x), in radians. The result is between -pi and pi. The vector in the plane from the origin to point (x, y) makes this angle with the positive X axis. The point of atan2() is that the signs of both inputs are known to it, so it can compute the correct quadrant for the angle. For example, atan(1) and atan2(1, 1) are both pi/4, but atan2(-1, -1) is -3*pi/4.
So it's pretty clear: the outputs are different because of the signs of ImZ
and ImR
. atan2
returns the appropriate quadrant, unlike atan
.