为什么Quaternion.FromToRotation(rotation * axis, axis) * rotation 可以限制一个DOF?

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

我从 Unity 插件 Final IK 中看到了这行代码。

整个函数是这样的:

//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;
}

这看起来既优雅又快速,但我不明白它是如何工作的。为什么这可以限制一个DOF?

直觉上,FromToRotation() 部分正在恢复围绕 axis 以外的轴的任何旋转分量。这是通过将旋转轴推回 axis.

来实现的

更详细一点:您想要找到一个接近 R 的旋转 R1DOF 并且被限制在一个自由度内(关于 axis 的旋转)。因此,您希望将 axis 转换为 R 保留 axis:

R1DOF * axis = axis

我在这里稍微滥用了符号,因为 R 是一个四元数,而四元数的转换不仅仅是一次乘法。让我们声明 * 是转换运算符。

现在,我们将 R1DOF 表示为 M * R,其中 M 是将 R * axis 映射到 axis 的修改旋转。为了清楚起见,我们调用 axisAfterR = R * axis。如果我们这样做,那么:

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

自从我们定义 MaxisAfterR 映射到 axis 后,我们有

             = axis

这正是我们想要的。

因此,axis(以及它的所有倍数)是 R1DOF 的不动点。因此,R1DOF 是关于 axis 的旋转。