Python atan or atan2, what should I use?

Question:

My formula
f=arctan(ImZ/ReZ)

There are two options:

Option 1 (atan):

ImZ=-4.593172163003
ImR=-4.297336384845

>>> z=y/x
>>> f1=math.atan(z)
>>> f1
0.8186613519278327

Option 2 (atan2)

>>> f=math.atan2(y,x)
>>> f
-2.3229313016619604

Why are these two results different?

Asked By: Richard Rublev

||

Answers:

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 results for each x,y

Atan2 result is always between -pi and pi.

Reference:
https://en.wikipedia.org/wiki/Atan2

Answered By: Abdul Rauf

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.

Answered By: DevShark

A formula to have an angle counter clockwise from 0,that is the positive axis of x,

to 2pi for any value of x and y. For x=y=0 the result is undefined.

f(x,y)=pi-pi/2*(1+sign(x))*(1-sign(y^2))-pi/4*(2+sign(x))*sign(y)
       -sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
Answered By: theodore panagos

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

Answered By: Girardi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.