将 angular 速度积分为四元数旋转
Integrate angular velocity as quaternion rotation
我(有点盲目地)在物理刚体模拟中使用四元数进行旋转有一段时间了,但最近开始对四元数旋转的一般定义方式和我是如何做的感到困惑(基于游戏物理学一书开发人员)。
在书中你有一个 angular 速度 angVel 和一个时间步长 dt 以及一个初始方向。
步骤如下
方向 += 0.5*方向*angVel * dt
其中四元数向量乘法是通过首先将向量 xyz 转换为四元数 xyz 来完成的,0
这行得通,但在其他任何地方,该过程都是生成一个四元数,它定义了 dt 上的时间积分 angVel,然后将其乘以方向。它本质上将 angVel*dt 转换为旋转(非常有意义),然后通过乘法将其应用于原始方向,如此处所示具有更好的语法 https://math.stackexchange.com/questions/39553/how-do-i-apply-an-angular-velocity-vector3-to-a-unit-quaternion-orientation
我的问题是上面的 0.5 * 四元数 * 向量 * 标量在概念上 是 以及 添加 这个结果四元数到我的方向是,考虑到你通常乘法而不是加法来旋转。
为了正确关闭它,我将在此处扩展 minorlogic 的评论。
由于 angular 速度 v,旋转四元数 q 的时间导数给出为
dq/dt = 0.5*q*v
这里 v 是定义 angular 速度的形式,其中矢量方向定义旋转轴,大小定义旋转速度。 v 在 "local space" 中进一步给出。如果 v 在 "world space" 中,q 和 v 的乘法顺序将相反。
然后出题表达
orientation += 0.5*orientation*angVel * dt
事实证明,这只是使用此时间导数随时间进行的正常一阶积分。然而,它不是很准确,需要不断地重新归一化方向四元数,但它简单快速,并且不像轴角转换那样使用 sin 或 cos。
精度问题和归一化要求可以通过查看单位四元数来解释,正确的旋转必须是作为放置在 4d 球体上的点和导数作为垂直于该球体表面的向量。很明显,如果你简单地将这样一个向量添加到表面上的这样一个点,你会得到一个新点,它不再是 on 表面,而是略高于表面。多少取决于这个向量的大小和你乘以你的导数向量的时间步长。然后需要归一化才能将其放回到表面。
明确回答问题。当您 有 一个方向和一个已知的旋转四元数来旋转它时,使用乘法方法,而加法方法试图通过导数的一阶积分来达到相同的目标。
参见this answer——您给出的代码是四元数求幂的一阶泰勒级数展开,用于在离散时间间隔dt
上对angular速度进行积分.如果您想要一种更准确的方法将 angular 速度转换为旋转,您可以使用 post 中的另一个代码示例(第一个代码示例),使用实际的四元数求幂,而不是泰勒级数近似。
如果您对数学感兴趣,请参阅 this derivation。
我(有点盲目地)在物理刚体模拟中使用四元数进行旋转有一段时间了,但最近开始对四元数旋转的一般定义方式和我是如何做的感到困惑(基于游戏物理学一书开发人员)。
在书中你有一个 angular 速度 angVel 和一个时间步长 dt 以及一个初始方向。
步骤如下
方向 += 0.5*方向*angVel * dt
其中四元数向量乘法是通过首先将向量 xyz 转换为四元数 xyz 来完成的,0
这行得通,但在其他任何地方,该过程都是生成一个四元数,它定义了 dt 上的时间积分 angVel,然后将其乘以方向。它本质上将 angVel*dt 转换为旋转(非常有意义),然后通过乘法将其应用于原始方向,如此处所示具有更好的语法 https://math.stackexchange.com/questions/39553/how-do-i-apply-an-angular-velocity-vector3-to-a-unit-quaternion-orientation
我的问题是上面的 0.5 * 四元数 * 向量 * 标量在概念上 是 以及 添加 这个结果四元数到我的方向是,考虑到你通常乘法而不是加法来旋转。
为了正确关闭它,我将在此处扩展 minorlogic 的评论。
由于 angular 速度 v,旋转四元数 q 的时间导数给出为
dq/dt = 0.5*q*v
这里 v 是定义 angular 速度的形式,其中矢量方向定义旋转轴,大小定义旋转速度。 v 在 "local space" 中进一步给出。如果 v 在 "world space" 中,q 和 v 的乘法顺序将相反。
然后出题表达
orientation += 0.5*orientation*angVel * dt
事实证明,这只是使用此时间导数随时间进行的正常一阶积分。然而,它不是很准确,需要不断地重新归一化方向四元数,但它简单快速,并且不像轴角转换那样使用 sin 或 cos。
精度问题和归一化要求可以通过查看单位四元数来解释,正确的旋转必须是作为放置在 4d 球体上的点和导数作为垂直于该球体表面的向量。很明显,如果你简单地将这样一个向量添加到表面上的这样一个点,你会得到一个新点,它不再是 on 表面,而是略高于表面。多少取决于这个向量的大小和你乘以你的导数向量的时间步长。然后需要归一化才能将其放回到表面。
明确回答问题。当您 有 一个方向和一个已知的旋转四元数来旋转它时,使用乘法方法,而加法方法试图通过导数的一阶积分来达到相同的目标。
参见this answer——您给出的代码是四元数求幂的一阶泰勒级数展开,用于在离散时间间隔dt
上对angular速度进行积分.如果您想要一种更准确的方法将 angular 速度转换为旋转,您可以使用 post 中的另一个代码示例(第一个代码示例),使用实际的四元数求幂,而不是泰勒级数近似。
如果您对数学感兴趣,请参阅 this derivation。