旋转矩阵与四元数

来源:互联网 发布:淘宝微能量运动旗舰店 编辑:程序博客网 时间:2024/06/12 20:30

旋转矩阵与四元数

在计算机图形学的学习中,几何变换(Transformations)是一块重要的内容,我们使用齐次坐标(Homogeneous coordinates)描述点和向量,使用变换矩阵描述平移、旋转等变换。

而在平移、旋转、缩放这几种变换中,又以旋转的情况最为复杂。实际上,计算机图形学中三维空间的旋转不仅仅有旋转矩阵一种表达形式,欧拉角(Euler angles)和四元数(Quaternions)也是常用的方法。

旋转矩阵

三维空间中的一个点 PP ,我们用齐次坐标表示:

P=[x,y,z,w]TP=[x,y,z,w]T

我们首先考虑分别绕 X 轴、Y 轴、Z 轴旋转一定角度的情况。

绕坐标轴旋转

绕坐标轴旋转

设 PP 绕 X 轴、Y 轴、Z 轴的旋转角度分别为 ααββ 和 θθ

我们使用右手坐标系,旋转角度的正向由右手定则确定。

点绕坐标轴旋转可以考虑点在相应坐标平面上投影的旋转。比如绕 Y 轴旋转,那么考虑点 PP 在 X-Z 平面上的投影的旋转,如下图所示:

绕Y轴旋转绕Y轴旋转

假设点 PP 在 X-Z 平面上的投影点与坐标原点连成的向量长度为 L ,那么根据简单的平面几何知识,我们可以得到:

[x1z1]=[cosβsinβsinβcosβ][xz][x1z1]=[cosβsinβ−sinβcosβ][xz]

用齐次坐标表示绕Y轴的旋转为:

x1y1z1w1=cosβ0sinβ00100sinβ0cosβ00001xyzw[x1y1z1w1]=[cosβ0sinβ00100−sinβ0cosβ00001][xyzw]

同理可分别得到绕X轴与绕Y轴的情况。

绕X轴旋转:

x2y2z2w2=10000cosαsinα00sinαcosα00001xyzw[x2y2z2w2]=[10000cosα−sinα00sinαcosα00001][xyzw]

绕Z轴旋转:

x3y3z3w3=cosθsinθ00sinθcosθ0000100001xyzw[x3y3z3w3]=[cosθ−sinθ00sinθcosθ0000100001][xyzw]

我们可以将绕X、Y和Z坐标轴的旋转矩阵分别记为 Rx(α),Ry(β),Rz(θ)Rx(α),Ry(β),Rz(θ),则有:

Rx(α)=10000cosαsinα00sinαcosα00001Rx(α)=[10000cosα−sinα00sinαcosα00001]

Ry(β)=cosβ0sinβ00100sinβ0cosβ00001Ry(β)=[cosβ0sinβ00100−sinβ0cosβ00001]

Rz(θ)=cosθsinθ00sinθcosθ0000100001Rz(θ)=[cosθ−sinθ00sinθcosθ0000100001]

旋转矩阵可以通过其他旋转矩阵复合得到(矩阵乘法)。

四元数

从前面的讨论我们发现三角度系统(three-angle system)无法很好地处理旋转的插值。下面介绍四元数(Quaternions)以及如何利用四元数描述旋转。


四元数的定义

四元数是由数学家 William Rowan Hamilton 于1843年所发明的数学概念,是复数的推广,可以说是“三维的复数”,形式为 w+x i+y j+z kw+x i+y j+z k ,其中 i,j,ki,j,k 的关系如下:

i2=j2=k2=1ij=ji=kik=ki=jjk=kj=ii2=j2=k2=−1i⋅j=−j⋅i=ki⋅k=−k⋅i=jj⋅k=−k⋅j=i

假设有两个四元数:

q1=w1+x1 i+y1 j+z1 kq2=w2+x2 i+y2 j+z2 kq1=w1+x1 i+y1 j+z1 kq2=w2+x2 i+y2 j+z2 k

四元数的加法定义如下:

q1+q2=(w1+w2)+(x1+x2) i+(y1+y2) j+(z1+z2) kq1+q2=(w1+w2)+(x1+x2) i+(y1+y2) j+(z1+z2) k

四元数的乘法定义,利用简单的分配律定义如下:

q1q2=(w1w2x1x2y1y2z1z2)+(w1x2+x1w2+y1z2z1y2) i+(w1y2x1z2+y1w2+z1x1) j+(w1z2+x1y2y1x2+z1w2) kq1⋅q2=(w1⋅w2−x1⋅x2−y1⋅y2−z1⋅z2)+(w1⋅x2+x1⋅w2+y1⋅z2−z1⋅y2) i+(w1⋅y2−x1⋅z2+y1⋅w2+z1⋅x1) j+(w1⋅z2+x1⋅y2−y1⋅x2+z1⋅w2) k

为了方便表示,我们将四元数记为:

q=(x,y,z,w)=(v⃗ ,w)q=(x,y,z,w)=(v→,w)

注意,这里四元数的表示形式和“齐次坐标”长得一样,但是它们之间没什么关系

四元数常常用来表示旋转,很多人将其理解为“w表示旋转角度,v表示旋转轴”,也是错误的!

正确的理解应为:“w与旋转角度有关,v与旋转轴有关”。

四元数的模(norm)定义为

|q|=x2+y2+z2+w2|q|=x2+y2+z2+w2

模为1的四元数称为单位四元数(Unit quaternions)。

四元数的共轭(conjugate)定义为:

q=(v⃗ ,w)q∗=(−v→,w)

四元数的倒数定义为:

1/q=q/|q|21/q=q∗/|q|2


四元数与旋转

这里直接给出结论:如果把单位四元数表示为:

q=(n⃗ sinθ2, cosθ2)q=(n→⋅sinθ2, cosθ2)

的形式,那么该单位四元数可以表示绕轴 n⃗ n→
进行 θθ 角的旋转。

该单位四元数对应的旋转矩阵为

R(q)=12(y2+z2)2(xy+zw)2(xzyw)2(xyzw)12(x2+z2)2(yz+xw)2(xz+yw)2(yzxw)12(x2+y2)R(q)=[1−2(y2+z2)2(xy−zw)2(xz+yw)2(xy+zw)1−2(x2+z2)2(yz−xw)2(xz−yw)2(yz+xw)1−2(x2+y2)]

这里的推导用到了轴-角旋转表示中的Rodrigues’ rotation formula,具体证明这里不展开了,有兴趣的可以查阅相关资料。

我们发现用四元数描述旋转需要的存储空间很小,更为关键的是可以使用被称为球面线性插值(Slerp Algorithm)的方法对四元数进行插值运算,从而解决了平滑旋转的插值问题。

在 OpenGL 或者 DirectX 中我们通常使用模型视图矩阵来进行几何变换,当我们希望实现光滑旋转、对旋转进行插值时,就可以利用四元数这一工具。处理过程为:

  • 模型视图矩阵 -> 四元数
  • 使用四元数进行运算
  • 四元数 -> 模型视图矩阵


0 0
原创粉丝点击