[Math] vertical angle between vectors

angletrigonometryvectors

I'm trying to find out the horizontal and vertical angle between two vectors to determine if an object is withing the field of view of a person by comparing these angles to the maximum horizontal and vertical angles that a human can see.

If human is at position $p_h$, the direction he is facing is given by $a$ and an object is at position $p_o$, then $p_o-p_h$ gives us a vector $b$ from $p_h$ to $p_o$.

To know if the object is within the hortizontal field of view, I set $a_y$ and $b_y$ to 0 and calculate the angle between the vectors by
$$\theta = cos^{-1}\frac{a\cdot b}{|a|\cdot|b|}$$

and then comparing the result to the visual field limits.

However to get the vertical angle, it seems I can't just set $a_x$ and $b_x$ to 0 as it is apparently not equivalent to setting $a_z$ and $b_z$ to 0.

I thought it should be equivalent, but after seeing some visualizations I'm convinced they are not.

I realize this should be relatively trivial, but I just can't wrap my head around it and I've been stuck on this for the last few hours. I've also looked for this in google as I thought it would be a rather common problem, but I can't find exactly what I'm looking for.

How do I get the vertical angle between these two vectors?


Here are a few graphs:

The sample vectors could be $a = (4,3,1)$ and $b= (2,7,9)$

In this site z is up, so please don't get confused.

First here is the 3D plot
enter image description here

Then we can project it to a top down view (equivalent to ignoring the y or in this case z component and look at the angle $\theta$). This way we get the horizontal angle between the vectors

enter image description here

If we then try to do the same for the vertical angle, we look at the side and front views and we can see that $\beta \neq \gamma $

enter image description here
enter image description here

Best Answer

You can’t really measure the “vertical” angle between the vectors via orthogonal projection because that distorts the angle. The underlying reason that projecting onto the $x$-$y$ plane (in the second coordinate system in the question) works for the horizontal angles but in general there’s no orthogonal projection that will get the vertical angles right is that all of the yaw rotations use the same rotation axis, but pitch rotations don’t.

You can, however, project the vectors/points onto the unit sphere, i.e., convert to spherical coordinates: $$\theta=\arccos{z\over\sqrt{x^2+y^2+z^2}} \\ \varphi = \arctan\frac yx.$$ (We don’t care about $\rho$, the distance from the origin, here.) You need to select the correct quadrant for the arc tangent, but math packages have a built-in variant of this function that takes care of this for you. Note, too, that $\theta$ increases downwards from the $z$-axis. Since there’s no camera roll, the horizontal visual angular separation is just the difference between the azimuths $\varphi$ and the vertical visual angular separation the difference in inclination $\theta$.

Using your example of $a=(4,3,1)$ and $b=(2,7,9)$, we have $\varphi_a=\arctan\frac34\approx36.870°$ and $\varphi_b=\arctan\frac72\approx74.055°$, for a difference of approximately $37.185°$, well within the field of vision. This matches the angle obtained from the projections onto the $x$-$y$ plane. It’s probably less computationally expensive to use the latter method since you can compare directly against $\cos 80°$ instead of computing an arc cosine, but this really only works because the visual field is horizontally symmetric. If you had different angles to the left and right, using the arc tangent is better since cosine doesn’t distinguish between different directions.

For the vertical angles, we get $\theta_a=\arctan 5\approx78.690°$ and $\theta_b=\arctan{\sqrt{53}\over9}\approx38.969°$ for a difference of $39.721°$, also within the field of view.

It’s also possible to compare the vertical angles by rotating $b$ so that it lies in the same vertical plane as $a$, but that seems like more work than just converting to spherical coordinates.

If you have to check a lot of points for visibility, computing all of those inverse trigonometric functions could get expensive. The field of view is bounded by four planes through the origin, so an alternative approach is to compute the equations $ax+by+cz=0$ ($\mathbf n\cdot\mathbf x=0$ in vector form) of these planes that make up the sides of this pyramid. The sign of dot product of the normal to the plane $\mathbf n$ with an arbitrary point tells you on which side of the plane the point lies: if positive, then the point lies in the direction of $\mathbf n$ from the plane; if negative, it’s on the opposite side; if zero, the point, of course, lies on the plane. You can arrange for all of the normals to be inward-pointing, so that a point is visible iff all four of these test values are non-negative.

Related Question