在前面几个章节中,我们仅仅讨论了两个坐标系之间的坐标转换矩阵,涉及到四元素、方向余弦阵、欧拉旋转等各种表现形式,但并没有涉及到两个坐标系的平移。
首先看两个坐标系之间的坐标转换矩阵:
[ x i y i z i ] = M ⋅ [ x b y b z b ] ( 1 ) \begin{bmatrix} x_i\\y_i \\z_i \end{bmatrix}= M\cdot\begin{bmatrix} x_b \\y_b \\z_b \end{bmatrix} \qquad(1) ⎣⎡xiyizi⎦⎤=M⋅⎣⎡xbybzb⎦⎤(1)
M M M为3×3的矩阵。
如果两个坐标系之间仅仅是平移关系(原点不重合),则两坐标系的坐标关系:
[ x i y i z i ] = [ x b y b z b ] + [ T x T y T z ] ( 2 ) \begin{bmatrix} x_i\\y_i \\z_i \end{bmatrix}= \begin{bmatrix} x_b \\y_b \\z_b \end{bmatrix}+\begin{bmatrix} T_x \\T_y \\T_z \end{bmatrix} \qquad(2) ⎣⎡xiyizi⎦⎤=⎣⎡xbybzb⎦⎤+⎣⎡TxTyTz⎦⎤(2)
可以看出,式(1)和式(2)的形式不同。一个是矩阵与向量相乘,一个是两个向量相加。
在WebGL中,数据处理主要依赖于GPU,而不是CPU。而正如大多数人所知道的,GPU的处理速度之快得益于它可以高效地处理矩阵乘法和卷积。因此,无论是旋转变换还是平移变换,我们应尽量表达成矩阵运算,这样才能最大的高效利用GPU的优势。
而齐次坐标的引用可以使得诸如缩放、平移的计算全部转换为矩阵计算的形式,也就是说式(1)和式(2)的形式全部统一为矩阵形式,下面具体阐述。
我们使用长度为3的数组表示一个点在坐标系中的坐标分量,如:(x, y, z); 然而在表示一个向量的时候也是同样的表达方式:(x, y, z)。如果我们只看数组(x, y, z),鬼知道这是向量还是点,毕竟点与向量还是有很大区别的,点只表示位置,向量没有位置只有大小和方向。
为了区分点和向量我们给它加上一维,用长度为4的数组(x, y, z, w)来表达坐标,我们规定(x, y, z, 0)表示一个向量,(x, y, z, 1)表示一个点。这种用n+1维坐标表示n维坐标的方式称为齐次坐标。
设点P的齐次坐标为 [ x , y , z , 1 ] [x,y,z,1] [x,y,z,1]
使用齐次坐标可以将坐标的缩放、旋转、平移全部使用矩阵乘法表示:
P的位置在三个轴上分别缩放 [ S 1 , S 2 , S 3 ] [S_1,S_2,S_3] [S1,S2,S3]:
[ S 1 0 0 0 0 S 2 0 0 0 0 S 3 0 0 0 0 1 ] ⋅ [ x y z 1 ] = [ S 1 ⋅ x S 2 ⋅ y S 3 ⋅ z 1 ] ( 3 ) \begin{bmatrix} S_1 &0 &0 &0\\ 0 &S_2 &0 &0\\ 0 &0 &S_3 &0\\ 0 &0 &0 &1\end{bmatrix}\cdot \begin{bmatrix} x \\y \\z \\1\end{bmatrix} =\begin{bmatrix} S_1 \cdot x \\S_2\cdot y \\S_3\cdot z \\1\end{bmatrix}\qquad(3) ⎣⎢⎢⎡S10000S20000S300001⎦⎥⎥⎤⋅⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡S1⋅xS2⋅yS3⋅z1⎦⎥⎥⎤(3)
P的位置平移 [ T x , T y , T z ] [T_x,T_y,T_z] [Tx,Ty,Tz]:
[ 1 0 0 T x 0 1 0 T y 0 0 1 T z 0 0 0 1 ] ⋅ [ x y z 1 ] = [ x + T x y + T y z + T z 1 ] ( 4 ) \begin{bmatrix} 1 &0 &0 &T_x\\ 0 &1 &0 &T_y\\ 0 &0 &1 &T_z\\ 0 &0 &0 &1\end{bmatrix}\cdot \begin{bmatrix} x \\y \\z \\1\end{bmatrix} =\begin{bmatrix} x+T_x \\y+T_y \\z+T_z \\1\end{bmatrix}\qquad(4) ⎣⎢⎢⎡100001000010TxTyTz1⎦⎥⎥⎤⋅⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡x+Txy+Tyz+Tz1⎦⎥⎥⎤(4)
P绕X轴旋转后的坐标:
[ 1 0 0 0 0 cos θ − sin θ 0 0 sin θ cos θ 0 0 0 0 1 ] ⋅ [ x y z 1 ] = [ x cos θ ⋅ y − sin θ ⋅ z sin θ ⋅ y + cos θ ⋅ z 1 ] ( 5 ) \begin{bmatrix} 1 &0 &0 &0\\ 0 &\cos\theta &-\sin\theta &0\\ 0 &\sin\theta &\cos\theta &0\\ 0 &0 &0 &1\end{bmatrix}\cdot \begin{bmatrix} x \\y \\z \\1\end{bmatrix} =\begin{bmatrix} x\\ \cos\theta \cdot y-\sin\theta \cdot z \\ \sin\theta \cdot y+\cos\theta \cdot z \\ 1\end{bmatrix}\qquad(5) ⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤⋅⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡xcosθ⋅y−sinθ⋅zsinθ⋅y+cosθ⋅z1⎦⎥⎥⎤(5)
P绕Y轴旋转后的坐标:
[ cos θ 0 sin θ 0 0 1 0 0 − sin θ 0 cos θ 0 0 0 0 1 ] ⋅ [ x y z 1 ] = [ cos θ ⋅ x + sin θ ⋅ z y − sin θ ⋅ x + cos θ ⋅ z 1 ] ( 6 ) \begin{bmatrix} \cos\theta &0 &\sin\theta &0\\ 0 &1 &0 &0 \\ -\sin\theta &0 &\cos\theta &0\\ 0 &0 &0 &1\end{bmatrix}\cdot \begin{bmatrix} x \\y \\z \\1\end{bmatrix} =\begin{bmatrix} \cos\theta \cdot x+\sin\theta \cdot z \\ y\\ -\sin\theta \cdot x+\cos\theta \cdot z \\ 1\end{bmatrix}\qquad(6) ⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤⋅⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡cosθ⋅x+sinθ⋅zy−sinθ⋅x+cosθ⋅z1⎦⎥⎥⎤(6)
P绕Z轴旋转后的坐标:
[ cos θ − sin θ 0 0 sin θ cos θ 0 0 0 0 1 0 0 0 0 1 ] ⋅ [ x y z 1 ] = [ cos θ ⋅ x − sin θ ⋅ y sin θ ⋅ x + cos θ ⋅ y z 1 ] ( 7 ) \begin{bmatrix} \cos\theta &-\sin\theta &0 &0\\ \sin\theta &\cos\theta &0 &0\\ 0 &0 &1 &0\\ 0 &0 &0 &1\end{bmatrix}\cdot \begin{bmatrix} x \\y \\z \\1\end{bmatrix} =\begin{bmatrix} \cos\theta \cdot x-\sin\theta \cdot y \\ \sin\theta \cdot x+\cos\theta \cdot y \\ z\\ 1\end{bmatrix}\qquad(7) ⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤⋅⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡cosθ⋅x−sinθ⋅ysinθ⋅x+cosθ⋅yz1⎦⎥⎥⎤(7)
使用最多的是平移和旋转,见下图。
因此, o ′ − x ′ y ′ z ′ o'-x'y'z' o′−x′y′z′到 o − x y z o-xyz o−xyz的齐次坐标转换矩阵为::
C = [ U x V x N x T x U y V y N y T y U z V z N z T z 0 0 0 1 ] ( 11 ) C=\begin{bmatrix} U_x &V_x &N_x &T_x\\ U_y &V_y &N_y &T_y\\ U_z &V_z &N_z &T_z\\ 0 &0 &0 &1\end{bmatrix}\qquad(11) C=⎣⎢⎢⎡UxUyUz0VxVyVz0NxNyNz0TxTyTz1⎦⎥⎥⎤(11)
反之,坐标系 o − x y z o-xyz o−xyz到 o ′ − x ′ y ′ z ′ o'-x'y'z' o′−x′y′z′坐标系的齐次坐标转换矩阵为::
C − 1 = [ U x U y U z − U ⋅ T V x V y V z − V ⋅ T N x N y N z − N ⋅ T 0 0 0 1 ] ( 12 ) C^{-1}=\begin{bmatrix} U_x &U_y &U_z &-U\cdot T \\ V_x &V_y &V_z &-V\cdot T \\ N_x &N_y &N_z &-N\cdot T \\ 0 &0 &0 &1\end{bmatrix}\qquad(12) C−1=⎣⎢⎢⎡UxVxNx0UyVyNy0UzVzNz0−U⋅T−V⋅T−N⋅T1⎦⎥⎥⎤(12)
上面两式就是我们常用的齐次坐标转换矩阵。