点和向量
叉积
与二维向量叉积不同,三维向量叉积是一个向量,向量 a=(x1,y1,z1) 叉乘 b=(x2,y2,z2) 的计算公式如下
(x1,y1,z1)×(x2,y2,z2)=det[ijkx1y1z1x2y2z2]=(y1⋅z2–z1⋅y2,z1⋅x2–x1⋅z2,x1⋅y2–y1⋅x2)
该向量的方向满足右手定则(Right-hand rule),垂直于向量 a,b 所在平面
由于三维叉积的特殊性质,它常被用于计算平面法向量。
标量三重积
标量三重积(Scalar triple product),也称为混合积,是一种三个三维向量同时进行点积和叉积的计算,定义如下
(u×v)⋅w
根据对称性可以得到 u⋅(v×w)=v⋅(w×u)=w⋅(u×v)=−u⋅(w×v)。
三重积可以用于判断某个向量相对于某一平面的方向(判断该向量的方向指向平面之上或平面之下)。
如图,若 (u×v)⋅w>0,则向量 w 指向 uv 平面上方,否则指向 uv 平面下方。
仿射变换
这一节大部分内容来源于我的图形学课程笔记,符号定义与本文稍有不同:
- →v 表示向量 v。
- ∼p 表示点 p(坐标)。
- L 表示一个线性变换。
线性变换
线性变换 L 的性质为
- L(→v+→u)=L(→v)+L(→u)
- L(a→v)=aL(→v)
- L(→0)=→0
- 向量 →v 经过线性变换后仍然是一个向量。→v⇒L(→v)。
根据线性变换的性质可知
L(→v)=L(∑ici→bi)=∑iciL(→bi)
这里,(→b1,→b2,⋯,→bn) 表示线性空间的一组基,→v=∑ici→bi 就是这组基的一个线性组合(或者说 (c1,c2,⋯,cn) 就是该向量在这组基下的坐标)。我们将上式写成矩阵形式(以三维空间为例)
L(→v)=(L(→b1)L(→b2)L(→b3))(c1c2c3)
这里 L(→bi) 是一个向量,也可以表示为矩阵形式
L(→bi)=(→b1→b2→b3)(M1,iM2,iM3,i)
这里 M1,i,M2,i,M3,i 表示线性变换 L 的参数。根据上方推导即可得到
L(→v)=(L(→b1)L(→b2)L(→b3))(c1c2c3)=(→b1→b2→b3)(M1,1M1,2M1,3M2,1M2,2M2,3M3,1M3,2M3,3)(c1c2c3)=→bTMc
基变换
假设我们有两组基 →a,→b,并且
→ai=(→b1→b2→b3)(M1,iM2,iM3,i)
简记作 →aT=→bTM。
此时,对于一个向量 →v=→bTc,它在基 →a 下的坐标就是 →aTM−1c。
齐次坐标
在计算机图形学中,坐标系经常定义为原点 ∼o 加上一组基 →b,于是空间中的任意一个点 ∼p 就可以表示为
∼p=∼o+→v=∼o+∑ici→bi
注意到,上式也可以写成矩阵形式(以三维空间为例):
∼p=∼o+∑ici→bi=(→b1→b2→b3∼o)(c1c2c31)
这里,我们将一个三维的坐标 (c1,c2,c3)T 拓展到了四维 (c1,c2,c3,1)T,这第四个维度就被称为是虚拟坐标(dummy coordinate),目前它的取值始终是 1。这种四维的坐标表示被称为是齐次坐标(Homogeneous coordinates)。
引入了坐标系原点后的线性变换可以表示为:
∼o+3∑i=1ciL(→bi)=(→b1→b2→b3∼o)(M1,1M1,2M1,30M2,1M2,2M2,30M3,1M3,2M3,300001)(c1c2c31)
仿射变换
简单地说,仿射变换就是线性变换 + 平移变换。我们知道线性变换都可以用三维的矩阵乘法表示,而平移变换并不行(一般而言,平移变换就是向量加法),但是当我们引入了虚拟坐标后,平移变换就可以用四维矩阵乘法来表示了。
平移 (Translation)
对于一个平移变换 ∼p⇒∼p+→v,这里平移向量 →v 显然可以用基 →b 表示为
→v=(→b1→b2→b3)(M1,4M2,4M3,4)
这里 (M1,4M2,4M3,4) 就是向量 →v 在基 →b 下的坐标,因此平移变换可以看作是原点 ∼o 变成了 ∼o+→v:
∼o+→v+3∑i=1ci→bi=(→b1→b2→b3∼o)(100M1,4010M2,4001M3,40001)(c1c2c31)
伸缩 (Scaling)
对于一个伸缩变换,实际上就是基向量的模长改变了(可能还有方向),因此变换矩阵为
M=(sx0000sy0000sz00001)
这里 sx,sy,sz 表示三个基向量的伸缩倍率。
旋转 (Rotation)
首先,在三维空间中,旋转往往被表述为向量 P 绕某一旋转轴 A 旋转 θ 角,注意到向量旋转具有方向性,因此我们规定:沿着旋转轴 A 的负方向向正方向看去,逆时针旋转对应的角度为正。
首先回顾二维平面中的旋转,设 P=(x,y),Q 是向量 P 逆时针旋转 90∘ 得到的向量,即 (−y,x)。此时 P,Q 构成一组正交基,我们可以用这组正交基表示平面中的任意一个向量 P′。
设向量 P 逆时针旋转 θ 角后得到向量 P′,此时 P′ 可以分解为 Pcosθ+Qsinθ,该向量的两个分量为
{P′x=xcosθ–ysinθP′y=ycosθ+xsinθ
写成矩阵形式就是
(P′xP′y)=(cosθ−sinθsinθcosθ)(xy)
这个二维旋转矩阵很容易拓展到三维空间中绕 z 轴的旋转变换,注意到绕 z 轴的旋转不会改变向量在 z 轴的分量,于是旋转矩阵 Mz(θ) 应该表示为
Mz(θ)=(cosθ−sinθ0sinθcosθ0001)
同理推出绕 x 轴,y 轴旋转的变换矩阵
Mx(θ)=(1000cosθ−sinθ0sinθcosθ),My(θ)=(cosθ0sinθ010−sinθ0cosθ)
最后讨论向量 P 绕任意轴旋转 θ 角的表示方法,我们首先给出两个命题(证明略):
P×Q=[0−PzPyPz0−Px−PyPx0][QxQyQz]
projQP=P–P⋅Q|Q|2Q=1|Q|2[Q2xQxQyQxQzQxQyQ2yQyQzQxQzQyQzQ2z][PxPyPz]
假设旋转轴是一个单位向量 A,则向量 P 可以分解为分别与向量 A 平行和垂直的分量 projAP=(A⋅P)⋅A 和 perpAP=P–(A⋅P)⋅A,如下图
因为向量 P 绕向量 A 的旋转可以被分解为 projAP 和 perpAP 绕向量 A 的旋转,而 projAP 显然不变,因此只有 perpAP 发生了旋转。而 perpAP 绕向量 A 的旋转实际上实在垂直于 A 的二维平面上进行的,这个二维平面可以用基向量 (perpAP,A×P) 表示,因此 perpAP 绕向量 A 旋转 θ 角后的向量可以表示为
[P–(A⋅P)⋅A]cosθ+(A×P)sinθ
该向量再加上分量 projAP 就是 P 绕向量 A 旋转 θ 角后的结果 P′=Pcosθ+(A×P)sinθ+A(A⋅P)(1−cosθ)。这就是著名的罗德里格斯旋转公式(Rodrigues’ rotation formula)。
然后,根据上方的两个命题,将 (A⋅P)⋅A 和 A×P 替换为等效矩阵
P′=[100010001]Pcosθ+[0−AzAyAz0−Ax−AyAx0]Psinθ+[A2xAxAyAxAzAxAyA2yAyAzAxAzAyAzA2z]P(1−cosθ)
合并上述矩阵,并记 c=cosθ,s=sinθ,则旋转矩阵 MAθ 为
MAθ=[c+(1−c)A2x(1−c)AxAy−sAz(1−c)AxAz+sAy(1−c)AxAy+sAzc+(1−c)A2y(1−c)AyAz−sAx(1−c)AxAz−sAy(1−c)AyAz+sAxc+(1−c)A2z]
拓展到齐次坐标就是 (MAθ001)。
实际上,描述三维旋转变换最常用的方法是四元数。
四元数
定义
四元数(Quaternions)是复数的一种拓展,定义如下
q=w+xi+yj+zk
运算法则
四元数 q 通常被写成 q=w+v=<w,v>,其中 w 是标量部分,v=xi+yj+zk 是向量部分。这里 i,j,k 是复数在四维空间中的拓展,基础计算法则如下
i2=j2=k2=ijk=−1ij=−ji=kjk=−kj=iki=−ik=j
这里 i,j,k 之间的乘法规则定义可以类比叉积、右手法则之类的概念。
两个四元数 q1=w1+x1i+y1j+z1k,q2=w2+x2i+y2j+z2k 之间的乘法可以表示为
q1q2=(w1w2–x1x2–y1y2–z1z2)+(w1x2+x1w2+y1z2–z1y2)i+(w1y2–x1z2+y1w2+z1x2)j+(w1z2+x1y2–y1x2+z1w2)k
也可以用点乘、叉乘简写为
q1q2=w1w2–v1⋅v2+s1v2+s2v1+v1×v2
和复数相似地,四元数也有共轭的概念,q=w+xi+yj+zk 的共轭为 ¯q=w–xi–yj–zk。可以验证四元数 q 和它的共轭 ¯q 的乘积等于它的内积,即
q¯q=q⋅q=|q|2
由此可以求出四元数倒数的计算方法
q−1=¯qq2
四元数旋转
在仿射变换章节中,我们已经推出了向量 P 绕单位旋转轴 A 旋转 θ 角的罗德里格斯旋转公式
P′=Pcosθ+(A×P)sinθ+A(A⋅P)(1−cosθ)
这里向量 P,A 以及向量 P 分解出来的 projAP 和 perpAP 等向量都可以看作标量为 0 的四元数,记作
p=<0,P>a=<0,A>p∥=<0,projAP>p⊥=<0,perpAP>
同时,根据前文的推导已知
projAP=(A⋅P)⋅AperpAP=P–(A⋅P)⋅AperpAP′=perpAPcosθ+(A×P)sinθ
记 p′⊥=<0,perpAP′>,它表示 perpAP 绕轴 A 旋转 θ 角之后的四元数。对于等式 perpAP′=perpAPcosθ+(A×P)sinθ,这里 perpAP′ 和 perpAP 都可以表示为四元数形式,只剩下一个 A×P,这个叉积可以利用上方给出的四元数性质(ap=<−A⋅P,A×P>)进行转化。
因为 P=projAP+perpAP,所以 A×P=A×(projAP+perpAP)=A×perpAP,于是
A×P=ap⊥+A⋅perpAP=ap⊥
综上
p′⊥=p⊥cosθ+ap⊥sinθ=(cosθ+asinθ)p⊥
注意到,这里 cosθ+asinθ 实际上就是一个四元数,记作 q=<cosθ,asinθ>。
这个四元数有一个特殊性质
|q|=√cos2θ+(sinθa)⋅(sinθa)=√cos2θ+a2sin2θ=√cos2θ+sin2θ=1
最后,我们就能写出罗德里格斯旋转公式(四元数版):
p′=p′∥+p′⊥=p∥+qp⊥
再继续推导之前,我们先证明几个引理:
证明:
q2=<cosθ,asinθ><cosθ,asinθ>=<cos2θ–(asinθ)⋅(asinθ),(cosθsinθ+sinθcosθ)a+(asinθ)×(asinθ)>=<cos2θ–sin2θ,2acosθsinθ>=<cos2θ,asin2θ>
这个引理的几何意义就是绕旋转轴 a 旋转 θ 角两次等价于旋转 2θ 角一次。有了该引理后,我们对旋转公式进行变形
p′=p∥+qp⊥(q=<cosθ,asinθ>)=1⋅p∥+qp⊥=rr−1p∥+rrp⊥(r2=q,r=<cosθ2,asinθ2>)
这里我们引入了新的四元数 r,显然它也是一个单位四元数,满足性质 r−1=¯r,将这个性质代回等式中,则
p′=rr−1p∥+rrp⊥=r¯rp∥+rrp⊥
先展开等式左边:
LHS=qp∥=<α,βa>⋅<0,P∥>=<0−βaP∥,αP∥+0+βa×P∥>=<−βaP∥,αP∥>
再计算等式右边:
RHS=p∥q=<0,P∥>⋅<α,βa>=<0–βaP∥,0+αP∥+P∥×βa>=<−βaP∥,αP∥>=LHS
证明类似于引理 2:
LHS=qp⊥=<α,βa>⋅<0,P⊥>=<0,−βaP⊥,αP⊥+0+βa×P⊥>=<0,αP⊥+βa×P⊥>
RHS=¯p⊥q=<0,P⊥>⋅<α,−βa>=<0+βaP,αP⊥−P⊥×(−βa)>=<0,αP⊥+βa×P⊥>=LHS
于是,我们就能继续对公式 p′=r¯rp∥+rrp⊥ 进行变形
p′=r¯rp∥+rrp⊥=rp∥¯r+rp⊥¯r=r(p∥+p⊥)¯r=rp¯r=rpr−1
这就是最终的罗德里格斯旋转公式(四元数化简版),我们将上方所有的推导归纳为一个定理:
p′=qpq−1
此外,四元数的旋转是可以复合的。假设有两个表示沿着不同轴,不同角度旋转的四元数 q1,q2,我们先对某四元数 p=<0,p> 进行 q1 变换,得到 p′ 再进行 q2 变换,得到 p′′,这一过程用四元数旋转公式表示就是
p′=q1pq−11p′′=q2p′q−12=q2q1pq−11q−12
接下来证明,这两个旋转变换可以复合并写成以下形式
p′′=qnetpq−1net
首先给出一个引理:
¯q1¯q2=¯(q2q1)
证明如下
LHS=¯q1¯q2=<s,−v>⋅<t,−u>=<st−v⋅u,−su−tv+v×u>
RHS=¯(q2q1)=(<s,v>⋅<t,u>)∗=<st−v⋅u,su+tv−v×u>∗=LHS
上方推导中,x∗ 表示求 x 的共轭。于是有
p′′=q2q1pq−11q−12=q2q1p¯q1¯q2=q2q1p¯q2q1=(q2q1)p(q2q1)−1
也就是说 qnet=q2q1。这个复合旋转的计算也可以推广到 n 个旋转。
四元数旋转的矩阵形式
注意到,四元数乘法(q1=w1+x1i+y1j+z1k,q2=w2+x2i+y2j+z2k)实际上可以视为一种线性组合
q1q2=(w1w2–x1x2–y1y2–z1z2)+(w1x2+x1w2+y1z2–z1y2)i+(w1y2–x1z2+y1w2+z1x2)j+(w1z2+x1y2–y1x2+z1w2)k=[w1−x1−y1−z1x1w1−z1y1y1z1w1−x1z1−y1x1w1][w2x2y2z2]
同理有
q2q1=[w1−x1−y1−z1x1w1z1−y1y1−z1w1x1z1y1−x1w1][w2x2y2z2]
利用这个性质将 p′=qpq−1 写成矩阵形式,设 a=cosθ2,b=sinθ2Ax,c=sinθ2Ay,d=sinθ2Az,q=a+bi+cj+dk,单位旋转轴 a=(Ax,Ay,Az),则
qpq−1=qp¯q=[a−b−c−dba−dccda−bd−cba][abcd−ba−dc−cda−b−d−cba]p
实际上就是四元数 p 左乘 q,右乘 ¯q。利用 a2+b2+c2+d2=1 的性质,上式可以简化为
qpq−1=[100001−2c2−2d22bc−2ad2ac+2bd02bc+2ad1−2b2−2d22cd−2ab02bd−2ac2ab+2cd1−2b2−2c2]p
注意到这个变换矩阵很类似齐次坐标(最外圈不会对 p 进行任何变换),因此我们可以将这个矩阵压缩为 3×3 矩阵。总结以上推导,我们归纳得到了四元数旋转的矩阵形式
p′=qpq−1=[1−2c2−2d22bc−2ad2ac+2bd2bc+2ad1−2b2−2d22cd−2ab2bd−2ac2ab+2cd1−2b2−2c2]p
实际上,在上方矩阵形式的三维旋转公式中,已经不再涉及四元数运算了。