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…
- My suspicion is that (1) produces incorrect delta rotations for some input values, so combining the rotations does not yield the correct result. Why?
- 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}$.