07 - 四元数

定义

四元数的定义和复数类似,它有1个实部和3个虚部: 并且 我们经常将四元数的实部和虚部分开,并用一个三维向量来表示虚部:

性质

模长/范数

四元数的模长/范数(Norm)/大小的定义是:

加减法

只需将分量相加/减就行:

乘法

首先是四元数与标量的乘法,只需将标量乘到四个分量上就行,遵守交换律。

然后是四元数之间的乘法,它 不遵守交换率,但遵守结合律和分配律:

  • 类复数表示的角度。四元数的乘积​为:

  • 向量表示的角度。四元数的乘积为:

还有四元数的点积:

共轭和逆

四元数的共轭表示为,是通过将四元数的矢量部分变负得到的。例如四元数的共轭为: 并且有 四元数的逆表示为,定义为四元数的共轭除以其大小: 并且有 其中单位四元数,因为它的模长是1,可以发现,单位四元数的​。

除此之外,两个四元数的“差”(这里指变换的差距)为:

对数(log)

定义四元数(表示绕旋转°),那么它的对数就是

指数(exp)

定义四元数,则它的指数是

幂运算

例如四元数的t次幂可以被表示为,一个单位四元数的t次幂等同于将它的旋转角度缩放至t倍。例如,如果表示围绕x轴顺时针旋转30°,那么表示围绕x轴顺时针旋转60°。

四元数使用最短弧表示角度位移,不能表示多圈旋转。不会绕x轴顺时针旋转240°,而是逆时针旋转120°。也就是说,四元数只会在意最终结果,而不在意过程

在数学上,四元数的取幂公式如下:

插值

球面线性插值Slerp

四元数的球面线性插值(Spherical Linear Interpolation)很有用,因为它允许在两个四元数之间平滑插值,它的定义如下: 是插值的起始四元数,是插值的结束四元数,t是间的变量,表示插值的距离因子,例如t=0时,结果就是

知道Slerp的定义后,接下来就要推导它的公式了。

,它俩角位移的差值为 然后根据幂运算,取这个差值的一小部分 最后利用四元数乘法让四元数的范围限定到起始四元数和结束四元数间 就能得到Slerp的公式了: 这是理论上的公式,但它的计算不仅涉及到多个四元数的乘法,而且还包括幂运算,在实际应用中的效率很低。

为了方便理解,直接从几何的角度出发,推导2D向量的Slerp公式,如图:

可用发现,,接下来就要想法儿确定的值了。

在以为斜边的直角三角形中,有 那么 同理可得 因此 类似的,我们最终得到实际的四元数Slerp公式 这样就得到实际运算时用到的四元数Slerp公式了。其中,

观察式子不难发现,当非常接近,即很小的时候,可能会导致除以0的问题。因此,这种情况下要使用简单的正规化线性插值。

正规化线性插值Nlerp

四元数的线性插值公式如下: 但插值结果却不是单位四元数,我们需要将它除以它的模长,就能转换为单位四元数了,这种插值方法就是正规化线性插值: 但线性插值的角速度变化并不像Slerp那样均匀。

转换为矩阵

公式如下:

参考资料

  • 3D数学基础 图形和游戏开发(第2版)

  • 四元数.pdf