Inverse Cosine in Python

In response to using inverse cosine to find return angles via math.acos, it's all fine and dandy so long as the angle is <=90* once you go past that, python will have no way of differentiating which angle you wanted.

Observe.

>>> math.cos(5)
0.28366218546322625

Above, I asked python to fetch me the cosine of a 5 radian angle, and it gave me .28~ Great, below I'll ask python to give me the radian which has a .28~ cosine. Should be 5, right? It literally just told me it was.

>>> math.acos(0.28366218546322625)
1.2831853071795865

Wrong! Python returns 1.28~ radians. The reason is obvious when plotted visually, 1.28rad has the same cosine as 5rad, they're inverse angles. Every angle shares the same sine with another angle (and -sine with two others). i.e. 5/175* share an equivalent sine. They share inversely proportional cosines .99~/-.99 respectively. Their -sine cousins would be 185 and 355. The relationship meme here is that all these angles share the same angular deflection from the horizontal axis. 5*.

The reason python returns 1.28 and not 5 is that all computers/calculators are based on an abacus-like data table of an angle/radian, its sine, cos, tan etc etc. So when i math.acos(x), python asks the kernal to look through that data table for whichever angle has a cosine of x, and when it finds it, it returns the first entry it appears with. and then python gives that angle to me.

Due to this shared, proportional symmetry, sin/cos ratios repeat frequently. And you are likely to see the same figure, multiple times. There's no way for python, or the OS, to determine the difference of which of the two angles you actually require without doing additional logic that takes into account the -/+ value of the angle's sine. Or, the angle's tangent.

1.28 Rad has  x cosine, y sine, z tan  (72*)
1.88 Rad has -x cosine, y sine, -z tan (108*)
4.39 Rad has -x cosine, -y sine, z tan (252*)
   5 Rad has  x cosine, -y sine, -z tan (288*)

or, viewed Cartesianly,

                       negX,posY | posX,posY
                            -----+-----
                       negX,negY |  posX,negY

1.88 Rad has -x cosine, y sine (108) | 1.28 Rad has  x cosine, y sine (72*)
                                -----+-----
4.39 Rad has -x cosine, -y sine (252)|    5 Rad has  x cosine, -y sine (288)

So if, for whatever reason, i need 5 radians to be chosen (say for a vector drawing or game to determine the various vectors enemies are from the player), i would have to do some type of if/then logic comparing the sines/tangents.


To augment the correct answers to use math.acos, it is also worth knowing that there are math functions suitable for complex numbers in cmath:

>>> import cmath
>>> cmath.acos(1j)
(1.5707963267948966-0.88137358701954294j)

Stick with math.acos if you're only interested in real numbers,


We have the acos function, which returns the angle in radians.

>>> import math
>>> math.acos(0)
1.5707963267948966
>>> _ * 2 - math.pi
0.0

The result of math.acos() is in radians. So you need to convert that to degrees.

Here is how you can do:

import math
res = math.degrees (math.acos (value))