Search code examples
c#unity-game-enginemathquaternions

Why can Quaternion.FromToRotation(rotation * axis, axis) * rotation limit one DOF?


I came across this line code from the Unity plugin Final IK.

The whole funtion is like this:

//Limits rotation to a single degree of freedom (along axis)

protected static Quaternion Limit1DOF(Quaternion rotation, Vector3 axis) 
{
  return Quaternion.FromToRotation(rotation * axis, axis) * rotation;
}

This seems elegant and fast, but I cannot understand how this can work. Why can this limit one DOF?


Solution

  • Intuitively, the FromToRotation() part is reverting any rotation component about an axis other than axis. It is doing this by pushing the rotated axis back to axis.

    In some more detail: You want to find a rotation R1DOF that is close to R and that is restricted to a single degree of freedom (rotation about axis). Hence, you want that transforming axis with R preserves axis:

    R1DOF * axis = axis
    

    I am slightly abusing notation here since R is a quaternion and transformation by a quaternion is not simply a single multiplication. Let's instead state that * is the transformation operator.

    Now, we are representing R1DOF as M * R, where M is a modification rotation that maps R * axis to axis. Let's call axisAfterR = R * axis for clarity. If we do this, then:

    R1DOF * axis = M * R * axis
                 = M * axisAfterR
    

    Since we defined M such that it maps axisAfterR to axis, we have

                 = axis
    

    which is just what we wanted.

    Hence, axis (and thereby all its multiples) are fixpoints of R1DOF. Therefore, R1DOF is a rotation about axis.