# 模型、世界、观察、裁剪空间的坐标转换
在 3D
图形编程中,模型、世界、观察和裁剪空间的坐标转换,是将 3D
对象从其原始位置转换到最终可以在屏幕上渲染的 2D
图像的关键步骤。
这些转换通常在图形渲染管线的顶点着色器阶段进行。
下面是每个空间的简要说明和它们之间的转换:
-
模型空间(Model Space):
-
模型空间是
3D
对象的本地坐标系统。 -
模型空间中的坐标用于定义对象的几何形状。
-
-
世界空间(World Space):
-
世界空间是整个场景的坐标系统。
-
在这个空间中,所有对象的位置都是相对于场景原点的。
-
模型空间中的坐标通过模型矩阵(Model Matrix)转换到世界空间。
-
转换公式为: World Position = Model Matrix × Model Position \text{World Position} = \text{Model Matrix} \times \text{Model Position} World Position=Model Matrix×Model Position
-
-
观察空间(View Space)/ 相机空间(Camera Space):
-
观察空间是从相机的视角定义的坐标系统。
-
在这个空间中,相机位于原点,并且面向负
Z
轴。 -
世界空间中的坐标通过视图矩阵(View Matrix)转换到观察空间。
-
转换公式为: View Position = View Matrix × World Position \text{View Position} = \text{View Matrix} \times \text{World Position} View Position=View Matrix×World Position
-
-
裁剪空间(Clip Space):
-
裁剪空间是用于透视除法和裁剪测试的坐标系统。
-
在这个空间中,坐标被标准化,使得深度值的范围在
-1
到1
之间。 -
观察空间中的坐标通过投影矩阵(Projection Matrix)转换到裁剪空间。
-
转换公式为: Clip Position = Projection Matrix × View Position \text{Clip Position} = \text{Projection Matrix} \times \text{View Position} Clip Position=Projection Matrix×View Position
-
-
规范化设备坐标(Normalized Device Coordinates | NDC):
-
裁剪空间的坐标经过透视除法后,会转换到规范化设备坐标。
-
在这个空间中,坐标的范围是
x
和y
在-1
到1
之间,z
在0
到1
之间。
-
-
屏幕空间(Screen Space):
-
最后,
NDC
中的坐标通过视口变换矩阵(Viewport Transformation)转换到屏幕空间。 -
这个空间中的坐标对应于最终显示在屏幕上的像素坐标。
-
转换公式为: Screen Position = Viewport Matrix × NDC Position \text{Screen Position} = \text{Viewport Matrix} \times \text{NDC Position} Screen Position=Viewport Matrix×NDC Position
-
这些转换涉及到矩阵乘法,其中模型矩阵、视图矩阵和投影矩阵是最重要的三个矩阵,它们共同定义了场景的变换。
开发者可以通过修改这些矩阵来改变场景的视觉效果,例如实现相机移动、对象旋转和视角变换等。
# 模型空间
是指一个物体在其自身坐标系中的表示。
每个三维模型都有一个独立的坐标系,这个坐标系定义了模型在其自身空间中的位置、方向和大小。
假设有一个立方体模型,其顶点坐标在模型空间中可能是 (-1, -1, -1)
到 (1, 1, 1)
,这些坐标是相对于立方体自身的中心点(原点)的。
当你将这个立方体放置到场景中时,你需要将其从模型空间转换到世界空间,这通常涉及平移、旋转和缩放操作。
# 世界空间
是指整个场景或世界的全局坐标系。
世界空间是一个全局坐标系,所有物体的位置、方向和大小都是相对于一个统一的参考点(通常是场景的原点)来定义的。
世界空间用于管理和组织整个场景中的所有物体。通过在世界空间中定义物体的位置和方向,可以方便地进行场景的渲染、碰撞检测、物理模拟等操作。
假设有两个立方体模型,每个立方体在模型空间中的顶点坐标都是 (-1, -1, -1)
到 (1, 1, 1)
。当你将这两个立方体放置到世界空间中时,你可以通过平移操作将第一个立方体放置在 (0, 0, 0)
,将第二个立方体放置在 (5, 0, 0)
。这样,在世界空间中,第一个立方体的顶点坐标将是 (-1, -1, -1)
到 (1, 1, 1)
,而第二个立方体的顶点坐标将是 (4, -1, -1)
到 (6, 1, 1)
。
# 模型空间转世界空间的例子
假设有两个模型:
-
模型
A
在其模型空间中,1
个单位长度表示1
厘米。 -
模型
B
在其模型空间中,1
个单位长度表示1
毫米。
我们希望在世界空间中,1
个单位长度表示 1
米。
缩放模型 A
:
-
模型
A
的单位长度是1
厘米,即0.01
米。 -
创建一个缩放矩阵,将模型
A
的所有顶点坐标按100
倍缩放。
缩放模型 B
:
-
模型
B
的单位长度是1
毫米,即0.001
米。 -
创建一个缩放矩阵,将模型
B
的所有顶点坐标按1000
倍缩放。
应用模型变换:
- 对缩放后的模型
A
和模型B
,分别应用平移和旋转矩阵,将它们转换到世界空间中的目标位置和方向。
通过上述步骤,模型 A
和模型 B
在世界空间中的单位长度将统一为 1
米,从而保持一致的比例。
# 观察空间
是指从摄像机或观察者的视角来看待场景的坐标系。
在这个空间中,摄像机位于原点,观察方向沿着 Z
轴的负方向,摄像机的上方向沿着 Y
轴正方向。
观察空间是一个局部坐标系,所有物体的位置和方向都是相对于摄像机的位置和方向来定义的。
物体从世界空间转换到观察空间通常涉及一个视图变换。这个变换将物体从世界坐标系转换到摄像机的局部坐标系。
在观察空间中,通常会进行裁剪操作,以去除摄像机视野范围之外的物体。裁剪操作通常在观察空间中进行,因为在这个空间中,摄像机的视野范围可以很容易地用一个视锥体来表示。
摄像机的视锥体在观察空间中定义,它决定了哪些对象会被渲染到视图中。视锥体包括近裁剪面和远裁剪面,以及摄像机的视场角。
假设有一个立方体在世界空间中的位置是 (5, 0, 0)
,并且摄像机位于 (0, 0, 5)
,观察方向沿着 Z
轴的负方向。通过视图变换,你可以将立方体从世界空间转换到观察空间。在这个过程中,立方体的位置会相对于摄像机的位置和方向进行调整。
作用:
-
裁剪和优化:在观察空间中,可以进行视锥体裁剪,这是一种优化技术,用于剔除那些不在摄像机视锥体内的对象,从而提高渲染效率。
-
光照和阴影计算:在观察空间中,可以计算相对于摄像机的光照和阴影效果,这对于动态光源和阴影的计算尤为重要。
-
透视投影:在观察空间中,可以应用透视投影,将
3D
坐标转换为2D
屏幕坐标,这种投影考虑了透视效果,即远处的物体看起来比近处的物体小。 -
深度缓冲:在观察空间中,可以计算每个像素的深度值,这有助于确定对象的前后顺序,以及处理遮挡关系。
# =====
# 仿射空间
仿射空间是向量空间(也叫线性空间)的扩展。
仿射空间是一个没有固定原点的向量空间,但保留了向量加法和数乘运算的结构。
点与向量:
在仿射空间中,点和向量是两个基本概念。
点表示位置,向量表示方向和大小。
每个向量的起点都是原点。
运算:
-
点与向量的加法:给定一个点 P P P 和一个向量 v \mathbf{v} v,它们的和 P + v P + \mathbf{v} P+v 是一个新的点 Q Q Q,表示从点 P P P 沿着向量 v \mathbf{v} v 的方向移动得到的点。
-
向量的加法:给定向量 v 1 \mathbf{v}_1 v1 和 v 2 \mathbf{v}_2 v2,它们的和 v 1 + v 2 \mathbf{v}_1 + \mathbf{v}_2 v1+v2 是一个新的向量,表示两个向量的合成方向。
-
向量的数乘:给定向量 v \mathbf{v} v 和标量 k k k,它们的积 k v k \mathbf{v} kv 是一个新的向量,表示向量 v \mathbf{v} v 按比例 k k k 缩放后的结果。
仿射组合:
在仿射空间中,一个点的位置可以通过一组基点的仿射组合来表示。
仿射组合是指一组点的线性组合,其系数之和为 1
。
给定一组点 P 1 , P 2 , … , P n P_1, P_2, \ldots, P_n P1,P2,…,Pn 和一组标量 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an,其中 a 1 + a 2 + ⋯ + a n = 1 a_1 + a_2 + \cdots + a_n = 1 a1+a2+⋯+an=1,仿射组合表示为:
P = a 1 P 1 + a 2 P 2 + ⋯ + a n P n P = a_1 P_1 + a_2 P_2 + \cdots + a_n P_n P=a1P1+a2P2+⋯+anPn
这个组合表示一个新的点 P P P,它是基点 P 1 , P 2 , … , P n P_1, P_2, \ldots, P_n P1,P2,…,Pn 的线性组合。
仿射变换:
仿射变换是一种保持仿射空间中线性组合关系的变换。
常见的仿射变换包括平移、缩放、旋转和剪切。
仿射空间的特点:
-
与向量空间不同,仿射空间没有固定的原点。基点的选择是任意的,只要它们线性无关即可。
-
仿射空间不涉及距离或角度的概念。它只关注点的线性关系。
# 仿射变换
仿射变换是一种保持仿射空间中线性组合关系的变换。
仿射变换可以表示为线性变换和平移的组合。
线性变换:
线性变换是一种保持向量加法和数乘运算的变换。在二维空间中,线性变换可以表示为一个矩阵乘法:
( x ′ y ′ ) = ( a b c d ) ( x y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} (x′y′)=(acbd)(xy)
其中 ( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd) 是变换矩阵。
平移:
平移是将所有点沿着某个方向移动固定距离的变换。在二维空间中,平移可以表示为:
( x ′ y ′ ) = ( x y ) + ( t x t y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} t_x \\ t_y \end{pmatrix} (x′y′)=(xy)+(txty)
其中 ( t x t y ) \begin{pmatrix} t_x \\ t_y \end{pmatrix} (txty) 是平移向量。
仿射变换的表示:
仿射变换可以表示为线性变换和平移的组合。在二维空间中,仿射变换可以表示为:
( x ′ y ′ ) = ( a b c d ) ( x y ) + ( t x t y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} t_x \\ t_y \end{pmatrix} (x′y′)=(acbd)(xy)+(txty)
其中 ( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd) 是线性变换矩阵, ( t x t y ) \begin{pmatrix} t_x \\ t_y \end{pmatrix} (txty) 是平移向量。
还可以表示为:
y = A x + b \mathbf{y} = A\mathbf{x} + \mathbf{b} y=Ax+b
-
A A A 是一个线性变换矩阵。
-
x \mathbf{x} x 是原始向量。
-
b \mathbf{b} b 是一个平移向量。
-
y \mathbf{y} y 是变换后的向量。
常见的仿射变换之平移:
( x ′ y ′ ) = ( 1 0 0 1 ) ( x y ) + ( t x t y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} t_x \\ t_y \end{pmatrix} (x′y′)=(1001)(xy)+(txty)
常见的仿射变换之缩放:
( x ′ y ′ ) = ( s x 0 0 s y ) ( x y ) + ( 0 0 ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} s_x & 0 \\ 0 & s_y \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} 0 \\ 0 \end{pmatrix} (x′y′)=(sx00sy)(xy)+(00)
其中 s x s_x sx 和 s y s_y sy 是缩放因子。
常见的仿射变换之旋转:
( x ′ y ′ ) = ( cos θ − sin θ sin θ cos θ ) ( x y ) + ( 0 0 ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} 0 \\ 0 \end{pmatrix} (x′y′)=(cosθsinθ−sinθcosθ)(xy)+(00)
其中 θ \theta θ 是旋转角度。
常见的仿射变换之剪切:
( x ′ y ′ ) = ( 1 k x k y 1 ) ( x y ) + ( 0 0 ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} 1 & k_x \\ k_y & 1 \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} 0 \\ 0 \end{pmatrix} (x′y′)=(1kykx1)(xy)+(00)
其中 k x k_x kx 和 k y k_y ky 是剪切因子。
# 仿射变换中的平移如何转换为线性变换?
在仿射变换中,平移是一种非线性变换,因为它不能通过简单的矩阵乘法来表示。
然而,通过引入齐次坐标,我们可以将平移转换为线性变换,从而使得仿射变换可以用单一的矩阵乘法来表示。
齐次坐标:
齐次坐标是一种在多维空间中表示点和向量的方法,通过增加一个额外的维度来实现。
在二维空间中,一个点的齐次坐标表示为 ( x , y , w ) (x, y, w) (x,y,w),其中 w w w 是齐次坐标中的权重因子。
通常情况下,我们使用 w = 1 w = 1 w=1 来表示二维空间中的点。
将平移转换为线性变换:
在二维空间中,平移变换可以表示为:
( x ′ y ′ ) = ( x y ) + ( t x t y ) \begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} x \\ y \end{pmatrix} + \begin{pmatrix} t_x \\ t_y \end{pmatrix} (x′y′)=(xy)+(txty)
其中 ( t x t y ) \begin{pmatrix} t_x \\ t_y \end{pmatrix} (txty) 是平移向量。
为了将平移转换为线性变换,我们引入齐次坐标,将二维点 ( x , y ) (x, y) (x,y) 表示为齐次坐标 ( x , y , 1 ) (x, y, 1) (x,y,1)。然后,平移变换可以表示为一个矩阵乘法:
( x ′ y ′ 1 ) = ( 1 0 t x 0 1 t y 0 0 1 ) ( x y 1 ) \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} x′y′1 = 100010txty1 xy1
仿射变换的齐次坐标表示:
通过引入齐次坐标,我们可以将仿射变换(包括线性变换和平移)表示为一个单一的矩阵乘法。在二维空间中,仿射变换可以表示为:
( x ′ y ′ 1 ) = ( a b t x c d t y 0 0 1 ) ( x y 1 ) \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} a & b & t_x \\ c & d & t_y \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} x′y′1 = ac0bd0txty1 xy1
其中 ( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd) 是线性变换矩阵, ( t x t y ) \begin{pmatrix} t_x \\ t_y \end{pmatrix} (txty) 是平移向量。
示例:
假设我们有一个点 P ( x , y ) P(x, y) P(x,y),我们希望对其进行平移变换,平移向量为 ( 2 3 ) \begin{pmatrix} 2 \\ 3 \end{pmatrix} (23)。使用齐次坐标,我们可以表示为:
( x ′ y ′ 1 ) = ( 1 0 2 0 1 3 0 0 1 ) ( x y 1 ) \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} = \begin{pmatrix} 1 & 0 & 2 \\ 0 & 1 & 3 \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} x′y′1 = 100010231 xy1
# 齐次坐标中 w = 0 表示什么意思?
在齐次坐标系中,一个点的坐标通常表示为 ( x , y , z , w ) (x, y, z, w) (x,y,z,w),其中 w w w 是一个非零的实数。
齐次坐标的一个重要特性是,通过将每个坐标除以 w w w,可以得到该点的标准欧几里得坐标 ( x / w , y / w , z / w ) (x/w, y/w, z/w) (x/w,y/w,z/w)。
在齐次坐标中, w = 0 w = 0 w=0 表示一个在无穷远处的点和方向。
在二维空间中, ( x , y , 0 ) (x, y, 0) (x,y,0) 表示一个无穷远处的点,而在三维空间中, ( x , y , z , 0 ) (x, y, z, 0) (x,y,z,0) 表示一个无穷远处的点。这种表示法在处理透视变换、投影变换和射影几何时非常有用。
我们知道一个点光源的无限远处是平行光,类似于太阳光,太阳是一个点光源,光线到地球后变成了平行光。因此平行光可以通过改变点光源位置向量对应的齐次坐标中的 w w w 的值来表示,当 w = 1 w=1 w=1 时,即还在点光源的原来位置,依旧是一个点光源。当 w = 0 w=0 w=0 时,即在点光源的无限远处,变为一个平行光。
# 线性变换的本质
在二维空间中,设两个基向量 x = ( 1 , 0 ) \mathbf {x} = (1,0) x=(1,0) 和 y = ( 0 , 1 ) \mathbf {y} = (0,1) y=(0,1),则任意一个向量 a = ( i , j ) \mathbf {a} = (i,j) a=(i,j) 可以表示为 a = i x + j y \mathbf {a} = i\mathbf {x} + j\mathbf {y} a=ix+jy。
当空间发生线性变换后,所有向量都会发生变换,包括基向量。
假设变换后的基向量为 x ′ = ( x 1 , y 1 ) \mathbf {x'} = (x_1,y_1) x′=(x1,y1) 和 y ′ = ( x 2 , y 2 ) \mathbf {y'} = (x_2,y_2) y′=(x2,y2),则变换后的向量 a \mathbf {a} a 可以表示为 a = i x ′ + j y ′ = i ( x 1 , y 1 ) + j ( x 2 , y 2 ) \mathbf {a} = i\mathbf {x'} + j\mathbf {y'} = i(x_1,y_1) + j(x_2,y_2) a=ix′+jy′=i(x1,y1)+j(x2,y2)。
写成矩阵形式,得到:
a = i [ x 1 y 1 ] + j [ x 2 y 2 ] = [ i x 1 i y 1 ] + [ j x 2 j y 2 ] = [ i x 1 + j x 2 i y 1 + j y 2 ] = [ x 1 x 2 y 1 y 2 ] [ i j ] \mathbf {a} = i \begin{bmatrix} x_1 \\ y_1 \end{bmatrix} + j \begin{bmatrix} x_2 \\ y_2 \end{bmatrix} = \begin{bmatrix} ix_1 \\ iy_1 \end{bmatrix} + \begin{bmatrix} jx_2 \\ jy_2 \end{bmatrix} = \begin{bmatrix} ix_1 + jx_2 \\ iy_1 + jy_2 \end{bmatrix} = \begin{bmatrix} x_1 & x_2 \\ y_1 & y_2 \end{bmatrix} \begin{bmatrix} i \\ j \end{bmatrix} a=i[x1y1]+j[x2y2]=[ix1iy1]+[jx2jy2]=[ix1+jx2iy1+jy2]=[x1y1x2y2][ij]
其中, [ x 1 x 2 y 1 y 2 ] \begin{bmatrix} x_1 & x_2 \\ y_1 & y_2 \end{bmatrix} [x1y1x2y2] 是变换矩阵。
x ′ = ( x 1 , y 1 ) \mathbf {x'} = (x_1,y_1) x′=(x1,y1) 是 x = ( 1 , 0 ) \mathbf {x} = (1,0) x=(1,0) 经过线性变换后的基向量, y ′ = ( x 2 , y 2 ) \mathbf {y'} = (x_2,y_2) y′=(x2,y2) 是 y = ( 0 , 1 ) \mathbf {y} = (0,1) y=(0,1) 经过线性变换后的基向量。
因此,线性变换的本质是将向量表示为基向量的线性组合,并通过变换矩阵将原来的基向量变换为新的基向量。
# 向量的构造以及平移不变性
向量的构造:
-
向量可以直接通过指定其分量来定义。
-
在二维空间中,向量 v = ( v 1 , v 2 ) \mathbf {v} = (v_1, v_2) v=(v1,v2) 可以通过指定 v 1 v_1 v1 和 v 2 v_2 v2 的值来定义。
-
在三维空间中,向量 v = ( v 1 , v 2 , v 3 ) \mathbf {v} = (v_1, v_2, v_3) v=(v1,v2,v3) 可以通过指定 v 1 v_1 v1、 v 2 v_2 v2 和 v 3 v_3 v3 的值来定义。
-
-
向量可以通过两个点的坐标差来计算。
-
在二维空间中,如果有点 A ( x 1 , y 1 ) A(x_1, y_1) A(x1,y1) 和点 B ( x 2 , y 2 ) B(x_2, y_2) B(x2,y2),那么从点 A A A 到点 B B B 的向量 v \mathbf {v} v 可以表示为: v = ( x 2 − x 1 , y 2 − y 1 ) \mathbf {v} = (x_2 - x_1, y_2 - y_1) v=(x2−x1,y2−y1)。
-
在三维空间中,如果有点 A ( x 1 , y 1 , z 1 ) A(x_1, y_1, z_1) A(x1,y1,z1) 和点 B ( x 2 , y 2 , z 2 ) B(x_2, y_2, z_2) B(x2,y2,z2),那么从点 A A A 到点 B B B 的向量 v \mathbf {v} v 可以表示为: v = ( x 2 − x 1 , y 2 − y 1 , z 2 − z 1 ) \mathbf {v} = (x_2 - x_1, y_2 - y_1, z_2 - z_1) v=(x2−x1,y2−y1,z2−z1)。
-
-
在几何学中,向量可以通过几何构造得到。
- 可以通过平行四边形法则或三角形法则来构造向量。
平移不变性:
-
平移不变性是指将一个向量从一个位置平移到另一个位置,向量的方向和大小保持不变。
-
平移不变性是指向量的方向和大小不会因为空间的平移而改变,但这并不妨碍它们在空间中进行平移变换,因为这种变换只是改变了它们的位置,而没有改变它们的方向和大小。
-
有点 A ( 1 , 2 ) A(1, 2) A(1,2) 和点 B ( 3 , 5 ) B(3, 5) B(3,5),那么从点 A A A 到点 B B B 的向量 v \mathbf {v} v 可以表示为: v = ( 3 − 1 , 5 − 2 ) = ( 2 , 3 ) \mathbf {v} = (3 - 1, 5 - 2) = (2, 3) v=(3−1,5−2)=(2,3),对空间进行平移变换后,此时点 A ( 4 , 5 ) A(4, 5) A(4,5) 和点 B ( 6 , 8 ) B(6, 8) B(6,8),但向量 v = ( 2 , 3 ) \mathbf {v} = (2, 3) v=(2,3) 的方向和大小保持不变。
# 复合变换
将多个变换矩阵按顺序相乘,以实现一系列连续的变换。
这种复合变换可以应用于向量或点,使其按照指定的顺序进行旋转、缩放、平移等操作。
假设我们有多个变换矩阵 T 1 , T 2 , … , T n T_1, T_2, \ldots, T_n T1,T2,…,Tn,我们希望对一个向量 v \mathbf{v} v 进行这些变换。复合变换的矩阵 T T T 可以通过将这些变换矩阵按顺序相乘得到:
T = T n ⋅ T n − 1 ⋅ … ⋅ T 2 ⋅ T 1 T = T_n \cdot T_{n-1} \cdot \ldots \cdot T_2 \cdot T_1 T=Tn⋅Tn−1⋅…⋅T2⋅T1
然后,我们可以通过以下方式对向量 v \mathbf{v} v 进行复合变换:
v ′ = T ⋅ v \mathbf{v}' = T \cdot \mathbf{v} v′=T⋅v
其中, v ′ \mathbf{v}' v′ 是变换后的向量。
具体例子:
假设我们有以下三个变换矩阵:
- 平移矩阵 T 1 T_1 T1:
T 1 = ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) T_1 = \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix} T1= 100001000010txtytz1
- 旋转矩阵 T 2 T_2 T2(绕 z z z 轴旋转 θ \theta θ 角度):
T 2 = ( cos θ − sin θ 0 0 sin θ cos θ 0 0 0 0 1 0 0 0 0 1 ) T_2 = \begin{pmatrix} \cos \theta & -\sin \theta & 0 & 0 \\ \sin \theta & \cos \theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} T2= cosθsinθ00−sinθcosθ0000100001
- 缩放矩阵 T 3 T_3 T3:
T 3 = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) T_3 = \begin{pmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} T3= sx0000sy0000sz00001
我们希望对向量 v = ( x y z 1 ) \mathbf{v} = \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} v= xyz1 进行先平移、再旋转、最后缩放的复合变换。
复合变换矩阵 T = T 3 ⋅ T 2 ⋅ T 1 T = T_3 \cdot T_2 \cdot T_1 T=T3⋅T2⋅T1。
计算复合变换矩阵 T T T:
T = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) ⋅ ( cos θ − sin θ 0 0 sin θ cos θ 0 0 0 0 1 0 0 0 0 1 ) ⋅ ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) T = \begin{pmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} \cos \theta & -\sin \theta & 0 & 0 \\ \sin \theta & \cos \theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix} T= sx0000sy0000sz00001 ⋅ cosθsinθ00−sinθcosθ0000100001 ⋅ 100001000010txtytz1
对向量 v \mathbf{v} v 进行复合变换:
v ′ = T ⋅ v \mathbf{v}' = T \cdot \mathbf{v} v′=T⋅v
这样, v ′ \mathbf{v}' v′ 就是经过平移、旋转和缩放后的向量。
矩阵乘法不满足交换律,即 A ⋅ B ≠ B ⋅ A A \cdot B \neq B \cdot A A⋅B=B⋅A。因此,变换矩阵的顺序非常重要。通常,变换的顺序是从右到左,即先应用最右边的矩阵,最后应用最左边的矩阵。
通过这种方式,我们可以将多个变换组合成一个单一的变换矩阵,从而简化计算和提高效率。
# 三维空间的旋转变换
在三维空间中,旋转变换的定义和性质会受到坐标系手性的影响,即左手坐标系和右手坐标系之间的差异。
右手坐标系:
-
伸出右手,拇指指向
X
轴的正方向。 -
食指指向
Y
轴的正方向。 -
中指指向
Z
轴的正方向。 -
确定一个旋转轴后,右手握住拳头,拇指指向旋转轴的正方向,四指弯曲的方向为旋转的正方向。
左手坐标系:
-
伸出左手,拇指指向
X
轴的正方向。 -
食指指向
Y
轴的正方向。 -
中指指向
Z
轴的正方向。 -
确定一个旋转轴后,左手握住拳头,拇指指向旋转轴的正方向,四指弯曲的方向为旋转的正方向。
左手坐标系,绕 X
轴旋转:
正方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R x ( θ ) R_x(\theta) Rx(θ) 可以表示为:
R x ( θ ) = ( 1 0 0 0 cos θ − sin θ 0 sin θ cos θ ) R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{pmatrix} Rx(θ)= 1000cosθsinθ0−sinθcosθ
反方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R x ( θ ) R_x(\theta) Rx(θ) 可以表示为:
R x ( θ ) = ( 1 0 0 0 cos θ sin θ 0 − sin θ cos θ ) R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & \sin\theta \\ 0 & -\sin\theta & \cos\theta \end{pmatrix} Rx(θ)= 1000cosθ−sinθ0sinθcosθ
右手坐标系,绕 X
轴旋转:
正方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R x ( θ ) R_x(\theta) Rx(θ) 可以表示为:
R x ( θ ) = ( 1 0 0 0 cos θ − sin θ 0 sin θ cos θ ) R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{pmatrix} Rx(θ)= 1000cosθsinθ0−sinθcosθ
反方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R x ( θ ) R_x(\theta) Rx(θ) 可以表示为:
R x ( θ ) = ( 1 0 0 0 cos θ sin θ 0 − sin θ cos θ ) R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & \sin\theta \\ 0 & -\sin\theta & \cos\theta \end{pmatrix} Rx(θ)= 1000cosθ−sinθ0sinθcosθ
左手坐标系,绕 Y
轴旋转:
正方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R y ( θ ) R_y(\theta) Ry(θ) 可以表示为:
R y ( θ ) = ( cos θ 0 sin θ 0 1 0 − sin θ 0 cos θ ) R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{pmatrix} Ry(θ)= cosθ0−sinθ010sinθ0cosθ
反方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R y ( θ ) R_y(\theta) Ry(θ) 可以表示为:
R y ( θ ) = ( cos θ 0 − sin θ 0 1 0 sin θ 0 cos θ ) R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & -\sin\theta \\ 0 & 1 & 0 \\ \sin\theta & 0 & \cos\theta \end{pmatrix} Ry(θ)= cosθ0sinθ010−sinθ0cosθ
右手坐标系,绕 Y
轴旋转:
正方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R y ( θ ) R_y(\theta) Ry(θ) 可以表示为:
R y ( θ ) = ( cos θ 0 sin θ 0 1 0 − sin θ 0 cos θ ) R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{pmatrix} Ry(θ)= cosθ0−sinθ010sinθ0cosθ
反方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R y ( θ ) R_y(\theta) Ry(θ) 可以表示为:
R y ( θ ) = ( cos θ 0 − sin θ 0 1 0 sin θ 0 cos θ ) R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & -\sin\theta \\ 0 & 1 & 0 \\ \sin\theta & 0 & \cos\theta \end{pmatrix} Ry(θ)= cosθ0sinθ010−sinθ0cosθ
左手坐标系,绕 Z
轴旋转:
正方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R z ( θ ) R_z(\theta) Rz(θ) 可以表示为:
R z ( θ ) = ( cos θ − sin θ 0 sin θ cos θ 0 0 0 1 ) R_z(\theta) = \begin{pmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix} Rz(θ)= cosθsinθ0−sinθcosθ0001
反方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R z ( θ ) R_z(\theta) Rz(θ) 可以表示为:
R z ( θ ) = ( cos θ sin θ 0 − sin θ cos θ 0 0 0 1 ) R_z(\theta) = \begin{pmatrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix} Rz(θ)= cosθ−sinθ0sinθcosθ0001
右手坐标系,绕 Z
轴旋转:
正方向(逆时针)旋转 θ \theta θ 角度,旋转矩阵 R z ( θ ) R_z(\theta) Rz(θ) 可以表示为:
R z ( θ ) = ( cos θ − sin θ 0 sin θ cos θ 0 0 0 1 ) R_z(\theta) = \begin{pmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix} Rz(θ)= cosθsinθ0−sinθcosθ0001
反方向(顺时针)旋转 θ \theta θ 角度,旋转矩阵 R z ( θ ) R_z(\theta) Rz(θ) 可以表示为:
R z ( θ ) = ( cos θ sin θ 0 − sin θ cos θ 0 0 0 1 ) R_z(\theta) = \begin{pmatrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix} Rz(θ)= cosθ−sinθ0sinθcosθ0001
总结:
旋转矩阵的逆矩阵即是旋转矩阵的转置矩阵。