Search code examples
quaternions

How to get opposite angle quaternion


I am calculating the quaternion rotation between 2 quaternions.

I know that Q1 = r x Q2, so I thought that r = Q1 x Q2* (asterisk means conjugate)

This however seems to give me the opposite of the angle I need.

ex. If Q1 and Q2 are Pi/2 off, I will get a quaternion of -Pi/2. How can I get the correct angle I need?

Example: I am looking 45 degrees left from forward. I am moving world forward. Relative to look, I am traveling 45 degrees to the right. I need r to be a rotation of 45 degrees right in this situation.

Thank you in advance


Solution

  • The description of the problem wasn't quite clear to me. I think that its probably best to derive the formula that you have found. Hopefully, this should allow you to understand (and visualize) why you might be getting the result that you are.

    Given two quaternions, Q1 and Q2, the relative quaternion rotation from Q1 to Q2 is:

    Quaternion = relativeRotation = Q1^(-1) * Q2
    

    Where Q1^(-1) denotes the inverse of Q1. You can think of this as applying the opposite rotation of Q1 to Q2. The result will be the relative rotation between the two. The inverse of a quaternion may be calculated by:

    Q^(-1) = (Q*) / ||Q||^2
    

    Where Q* denotes the conjugate of Q. I assume that you already know how to find the conjugate of a quaternion. Now, if Q is a unit quaternion, then both the norm and the square of the norm of Q is 1.0. Hence, we have:

    Q^(-1) = Q*
    

    This simplifies our formula to:

    Quaternion relativeRotation = (Q1*) * Q2
    

    Note that only unit quaternions represent rotations. However, since the Hamilton product of two unit quaternions is itself a unit quaternion, we don't need to normalize the result.

    Now, from this relative quaternion, you can determine the angle (in radians):

    float angle = 2.0f * acos(relativeRotation.w)
    

    Here, w is the scalar component of the quaternion and acos is the arccosine trigonometric function. This angle is about the axis:

    Vector3 axis = (relativeRotation.x, relativeRotation.y, relativeRotation.z)
    

    Now, having found both the angle and the axis, you should be able to visualize the rotation.

    Finally, as a side note, the Hamilton product (*) is not commutative. This means that (Q1*) * Q2 does not necessarily equal Q2 * (Q1*). Following the same derivation as above, the relative unit quaternion rotation from Q2 to Q1 can be calculated by:

    relativeRotation = (Q2*) * Q1