How to find an angle in range(0, 360) between 2 vectors?
I'm adapting my answer on Stack Overflow.
2D case
Just like the dot product is proportional to the cosine of the angle, the determinant is proprortional to its sine. And if you know the cosine and the sine, then you can compute the angle. Many programming languages provide a function atan2
for this purpose, e.g.:
dot = x1*x2 + y1*y2 # dot product
det = x1*y2 - y1*x2 # determinant
angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
3D case
In 3D, two arbitrarily placed vectors define their own axis of rotation, perpendicular to both. That axis of rotation does not come with a fixed orientation, which means that you cannot uniquely fix the direction of the angle of rotation either. One common convention is to let angles be always positive, and to orient the axis in such a way that it fits a positive angle. In this case, the dot product of the normalized vectors is enough to compute angles.
Plane embedded in 3D
One special case is the case where your vectors are not placed arbitrarily, but lie within a plane with a known normal vector $n$. Then the axis of rotation will be in direction $n$ as well, and the orientation of $n$ will fix an orientation for that axis. In this case, you can adapt the 2D computation above, including $n$ into the determinant to make its size $3\times3$. One condition for this to work is that the normal vector $n$ has unit length. If not, you'll have to normalize it. The determinant could also be expressed as the triple product:
$$\det(v_1,v_2,n) = n \cdot (v_1 \times v_2)$$
This might be easier to implement in some APIs, and gives a different perspective on what's going on here: The cross product is proportional to the sine of the angle, and will lie perpendicular to the plane, hence be a multiple of $n$. The dot product will therefore basically measure the length of that vector, but with the correct sign attached to it.