[Math] Calculating azimuth and elevation angles from direction cosines

coordinate systemspythonspherical coordinatestrigonometry

I've been scratching my head on this one for a while, I'm not very well versed in this subject area. Hopefully someone more mathematically gifted than I can assist in explaining why this code is not working as intended. The expected outcome is to be able to input vector i, j, k, calculate the direction cosines, transform the cartesian components x, y, z to the spherical components r, theta, phi, and have it output the calculated elevation and azimuth. For all the code examples below, I am running it in Python with NumPy and have omitted other portions of the code for brevity.

The rundown

These lines take an input of three variables i, j, k . These variables are transformed into direction cosines via

magnitude  = np.sqrt(i**2 + j**2 + k**2)
x = i / magnitude
y = j / magnitude
z = k / magnitude

Direction Cosines

These a transformed from cartesian coordinates to spherical via (In the program I’ve flipped theta to get the angles in the correct axis)

r = np.sqrt(x**2 + y**2 + z**2)
theta = np.arctan2(z, np.sqrt(x**2 + y**2))
phi = np.arctan2(y, x)

Cartesian to Spherical

Finally, theta and phi are converted from radians to degrees and output

elevation = np.degrees(theta)
azimuth = np.degrees(phi)

A few observations

Azimuth output works entirely as expected.

IN: i=1.0, j=0.0, k=0.0
OUT: el=0.0, az=0.0

IN: i=0.7071067811865476, j=0.7071067811865475, k=0.0
OUT: el=0.0, az=44.99999999999999

Elevation output is very close when angle is near 0 or 180 degrees, however error is significant at higher values (this applies for moving away from 0 degrees and 180 degrees).

IN: i=1.0, j=0.0, k=0.17364817766693033
OUT: el=9.851076116583906, az: 0.0 (Expected 10 degrees)

IN: i=1.0, j=0.0, k=0.766044443118978
OUT: el=37.453719557105146, az: 0.0 (Expected 50 degrees)

I'm assuming I must have made an error in the cartesian to spherical calculations and would greatly appreciate a fresh set of eyes!

Best Answer

For the coordinates \begin{align} i&=1.0,\\ j&=0.0,\\ k&=0.17364817766693033, \end{align}

consider the triangle with vertices $(0,0,0),$ $(1,0,0),$ $(1,0,0.17364817766693033)$. This is a right triangle with right angle at $(1,0,0).$ The other two vertices are the origin and your chosen point $(i,j,k).$

In this triangle, the leg opposite the origin has length $0.17364817766693033$ and the leg adjacent to the origin has length $1,$ so the ratio of those two legs, $0.17364817766693033/1 = 0.17364817766693033,$ is the tangent of the angle at the origin. That angle is $\arctan(0.17364817766693033) \approx 0.17193371309896594$ (in radians), which is approximately $9.8510761165839062$ degrees. Your program is giving the correct output.

You may have been thinking that by setting $k$ to the sine of $10$ degrees you should get a $10$ degree elevation. But the sine is the ratio of the opposite side of the triangle to the hypotenuse, that is, the ratio of $k$ to the magnitude $\sqrt{i^2+j^2+k^2}$. If you want to use $k=0.17364817766693033$ to get an elevation of $10$ degrees you need to ensure that $\sqrt{i^2+j^2+k^2} = 1,$ not that $i = 1.$ You can do this by setting $i$ to the cosine of $10$ degrees, or you can set $i$ to $1$ but set $k$ to the tangent of $10$ degrees.