# Signed angle between two 3D vectors with same origin within the same plane

The solution I’m currently using seems to be missing here.
Assuming that the plane normal is normalized (`|Vn| == 1`), the signed angle is simply:

For the right-handed rotation from Va to Vb:

`atan2((Va x Vb) . Vn, Va . Vb)`

For the left-handed rotation from Va to Vb:

`atan2((Vb x Va) . Vn, Va . Vb)`

which returns an angle in the range [-PI, +PI] (or whatever the available atan2 implementation returns).

`.` and `x` are the dot and cross product respectively.

No explicit branching and no division/vector length calculation is necessary.

Explanation for why this works: let alpha be the direct angle between the vectors (0° to 180°) and beta the angle we are looking for (0° to 360°) with `beta == alpha` or `beta == 360° - alpha`

``````Va . Vb == |Va| * |Vb| * cos(alpha)    (by definition)
== |Va| * |Vb| * cos(beta)     (cos(alpha) == cos(-alpha) == cos(360° - alpha)

Va x Vb == |Va| * |Vb| * sin(alpha) * n1
(by definition; n1 is a unit vector perpendicular to Va and Vb with
orientation matching the right-hand rule)

Therefore (again assuming Vn is normalized):
n1 . Vn == 1 when beta < 180
n1 . Vn == -1 when beta > 180

==>  (Va x Vb) . Vn == |Va| * |Vb| * sin(beta)
``````

Finally

``````tan(beta) = sin(beta) / cos(beta) == ((Va x Vb) . Vn) / (Va . Vb)
``````