How do I calculate the angle between two normalized vectors and an up direction?

4.1k Views Asked by At

How would one go about calculating the angle of a vector versus an "up" direction while looking down the axis of another vector? To illustrate what I'm asking, I've drawn two diagrams:

https://i.stack.imgur.com/cupWJ.jpg

In this image, you can see the general setup. The green arrows are the Y axis (up is positive, down is negative), the red arrows are the X axis (left is negative, right is positive), and the blue arrows are the Z axis (towards the screen is positive, away is negative).

The cyan and yellow arrows represent two normalized vectors (length = 1) centred around 0, 0, 0. The vectors can be anywhere in 3D space, I'm just using this as an example- the only thing guaranteed is that their length will always be 1 and the up direction will always be Vector(0, 1, 0).

https://i.stack.imgur.com/MWd1C.jpg

This is what I'm trying to figure out. I've oriented the camera so it points directly down the cyan arrow. I'm attempting to calculate the angle between the yellow arrow and the green (Y) axis while looking down the line specified by the cyan arrow.

I'm having troubles researching this on my own probably because I lack the vocabulary to adequately define my question (hence the diagrams). It seems like it might be possible to determine a rotation between the cyan arrow and a known axis, then rotate everything (including the yellow arrow) around the origin, at which point it's just a matter of using atan2() to determine the angle based on two coordinates of the yellow vector (ignoring the depth component), but I'm guessing there's probably a simpler way of doing things. What, if anything, might that be?

1

There are 1 best solutions below

4
On

If you have two vectors v=(v1, v2, v3) and w=(w1, w2, w3), then their dot product is v · w = v1 · w1 + v2 · w2 + v3 · w3. However another expression for their dot product is v · w = |v| |w| cos a, where |v| and |w| are the lengths of the two vectors, and a is the angle between them.

If you're representing these vectors as components (that is, the (v1, v2, v3)), then it's easy to calculate both their dot product and their respective lengths. Then cos a = v · w / (|v| |w|), and take arccos of that.

Working out rotations that would take one into the other is the hard way of doing this.

This is similar to various questions including 1 and 2, but I think they make it sound more complicated than it is.