[Math] Relative quaternion rotation (delta rotation) produces unstable results

3dgeometryquaternionsrotations

Disclaimer: I asked this question here on game development before.

Use case: I have a currentRotation quaternion and a targetRotation quaternion and need to calculate the relative rotation between them – as in: what rotation do I need to apply to transform an object (in a 3D scene) with currentRotation so that it has targetRotation.

The standard solution seems to be to calculate the relative rotation (1) $q_{delta} = {q_{current}}^{-1}*q_{target}$ and then (later at some point) combine it with the object's current rotation (2) $q_{new} = q_{delta} * q_{current}$ to actually transform the object.

Combining these, I get the formula (3) $q_{new} = {q_{current}}^{-1}*q_{target}*q_{current}$ which makes sense for me – ultimatively, I set the object's new rotation to be the target rotation.

This method works well for most cases of current-target-rotations, but unfortunately not for all – it is unstable and I don't understand why.

I created a codepen example that shows a problematic case. To be more precise, calculating the relative rotation from (0°, 170°, 10°) to (0°, 170°, -10°) which should be in my opinion (0°, 0°, -20°) (written as XYZ-euler angles for readability) fails – combining the original rotation with the delta rotation does not yield the expected target rotation, so $q_{target} \neq q_{new} = {q_{current}}^{-1}*q_{target}*q_{current}$ (see (3))

To wrap up: I am looking for your help to understand…

  1. My suspicion is that (1) produces incorrect delta rotations for some input values, so combining the rotations does not yield the correct result. Why?
  2. If so, how can I recognize "problematic input values" and handle them gracefully?

Best Answer

I think of quaternions as actions, not states. If I want to represent the state of an object's rotation by a quaternion, this must always be in reference to some unrotated state.

So when I see that the rotation of some object is represented by the quaternion $q_{current}$, I interpret it as "the object has been rotated away from its initial state by $q_{current}$."

If I want to reconfigure the object so it has rotation $q_{target}$, what I mean is, "I want to apply some rotation $q_{delta}$ to the object so that the result has been rotated from its initial state by $q_{new}$." When interpreted this way, we see that first we need to rotate back to the initial state, then to its new state: $$ q_{delta} = q_{target}q_{current}^{-1} $$

Remember that functions act on the left! The quaternions are acting on the object, so the actions should be read right-to-left: first we do $q_{current}^{-1}$, then we do $q_{target}$. As you say in your comment above, this why matrix libraries often define combination order from right to left --- they're also often interpreted as acting on vectors.

Does this make sense? Let's check: $$ q_{new} = q_{delta}q_{current} = q_{target}q_{current}^{-1}q_{current} = q_{target} $$ just as desired.

Note: Your (3) is not the same as the previous equation! In fact, quaternions do not commute, so the equation $q_{new} = q_{current}^{-1}q_{target}q_{current}^{-1}$ all but guarantees that $q_{new}$ will not be equal to $q_{target}$.

Related Question