Mathematics for 3D Game Programming and Computer Graphics 笔记 Chapter 3

Chapter 3  Transforms

在任何3D图形引擎中,常常需要把一组向量从一个空间转换到另一个空间,例如一个模型的坐标通常处于物体空间,在渲染时需要转换到相机空间.这章讨论在不同笛卡尔坐标系下的转换,例如缩放,平移,任意旋转.

3.1 线性变换

假设在坐标系 C 中有一点 P(x,y,z) , P 在另一坐标空间 C’ 中的坐标是 (x’,y’,z’) , (x’,y’,z’) 可以表示为 (x,y,z) 的线性函数,其中向量 U, V, W为 C 中基向量 (1, 0, 0), (0, 1, 0), (0, 0, 1) 在 C’ 中的坐标:

x'(x,y,z) = U1 x + V1 y + W1 z + T1
y'(x,y,z) = U2 x + V2 y + W2 z + T2
z'(x,y,z) = U3 x + V3 y + W3 z + T3

这构成了从 C 到 C’ 的线性变换,用矩阵来表示就是:

┌  ┐ ┌        ┐┌ ┐ ┌  ┐
│x'│ │U1 V1 W1││x│ │T1│
│y'│=│U2 V2 W2││y│+│T2│
│z'│ │U3 V3 W3││z│ │T3│
└  ┘ └        ┘└ ┘ └  ┘

从 C’ 到 C :

┌ ┐ ┌        ┐-1┌  ┐ ┌  ┐
│x│ │U1 V1 W1│  │x'│ │T1│
│y│=│U2 V2 W2│ (│y'│-│T2│)
│z│ │U3 V3 W3│  │z'│ │T3│
└ ┘ └        ┘  └  ┘ └  ┘

向量 T 可以看作是从 C 的原点 移动到 C’ 的原点的位移, 向量 U, V, W 表示坐标轴方向的变化.

多个线性变换矩阵可以通过相乘来结合成为一个变换矩阵,这个矩阵等价于依次进行一系列变换.

3.1.1 正交矩阵

一个 n×n 的可逆矩阵是正交矩阵当且仅当 M-1 = MT.

如果一个矩阵的各个列向量组成的向量集是正交集,这个矩阵是正交矩阵.

正交矩阵M在进行变换时不改变长度信息和角度信息.也就是说 ||MP|| = ||P||, (MP1)•(MP2) = P1•P2. 因此正交矩阵可以保存整个空间的结构,且只能表示旋转和镜像变换及其组合(平移?).镜像变换指在某个方向上点是镜像相反的.

3.1.2 Handedness

在三维空间中,一组基 V1, V2, V3 有一个属性:左手的或右手的.若 (V1×V2)•V3 > 0 我们称这组基是右手的,反之则称其为左手的.也就是说 右手系的两个基向量的叉积方向 与 第三个基向量方向 的夹角小于90度,左手系则大于90度.若对于一组右手的正交基,我们有 (V1×V2) = V3 .

奇数的镜像变换可以改变手性.偶数的镜像变换相当于一个旋转操作.所以任何一系列的镜像操作都相当于一个旋转操作加上最多一个镜像操作.一个3×3的矩阵可以通过检测矩阵的行列式的正负来判断是否经过镜像变换.若行列式小于0则包括镜像变换,该矩阵将把空间的手性改变.若行列式为正,则保存手性.

3.2 Scaling Transforms 缩放变换

如果在 x, y, z 方向上分别希望缩放 a, b, c 倍,则

   ┌     ┐┌  ┐
   │a 0 0││Px│
P'=│0 b 0││Py│
   │0 0 c││Pz│
   └     ┘└  ┘

如果要在任意三个轴上进行缩放操作,例如 a 倍在 U 轴, b 倍在 V 轴, c 倍在 W 轴,我们可以先转换到 UVW 空间,然后执行缩放操作,最后转换回 i, j, k 空间.

   ┌        ┐┌     ┐┌        ┐-1┌  ┐
   │Ux Vx Wx││a 0 0││Ux Vx Wx│  │Px│
P'=│Uy Vy Wy││0 b 0││Uy Vy Wy│  │Py│
   │Uz Vz Wz││0 0 c││Uz Vz Wz│  │Pz│
   └        ┘└     ┘└        ┘  └  ┘

3.3 Rotation Transforms

绕轴 A 旋转 θ 度 ( A指向我们时,逆时针转), 我们首先讨论点 P 在 x,y 平面上,绕 z 轴旋转的操作. 首先将 P 逆时针旋转90度,得到 Q = ( -Py, Px). 这样我们可以以 P 和 Q 为基来表示 P 旋转后的向量 P’.

P'可以表示为P和Q的线性组合

P’可以表示为P和Q的线性组合

P' = P cosθ + Q sinθ

Px' = Px cosθ - Py sinθ
Py' = Py cosθ + Px sinθ

     ┌          ┐
P' = │cosθ -sinθ│ P
     │sinθ  cosθ│
     └          ┘

扩展到三维空间,我们得到绕3个基本轴旋转的3×3矩阵:

        ┌            ┐
        │cosθ -sinθ 0│
Rz(θ) = │sinθ  cosθ 0│
        │   0    0  1│
        └            ┘
        ┌            ┐
        │1  0     0  │
Rx(θ) = │0 cosθ -sinθ│
        │0 sinθ  cosθ│
        └            ┘
        ┌             ┐
        │ cosθ 0 sinθ │
Ry(θ) = │   0  1   0  │
        │-sinθ 0 cosθ │
        └             ┘

3.3.1 绕任意轴旋转

假设要绕一个任意单位向量 A 旋转向量 P θ度,我们可以将 P 分解为垂直于A和平行于A的两部分,由于平行于A的部分不变,所以在垂直于A的平面按上面的方法计算出旋转后的向量再加上平行部分得到最后结果.过程懒得打了直接上结果吧…以后有心情再补.

c = cos θ, s = sin θ
        ┌                                         ┐
        │c+(1-c)AxAx   (1-c)AxAy-sAz (1-c)AxAz+sAy│
RA(θ) = │(1-c)AxAy+sAz c+(1-c)AyAy   (1-c)AyAz-sAx│
        │(1-c)AxAz-sAy (1-c)AyAz+sAx c+(1-c)AzAz  │
        └                                         ┘

3.4 Homogeneous Coordinates 齐次坐标

3×3矩阵无法表示平移操作,若要平移 T, 我们只能 P’ = MP + T, M为一个可逆矩阵, 当结合两个操作时, P’ = M2(M1P+T1)+T2,这个结果太乱糟糟了,当操作增多时就更加难以忍受了.

3.4.1 Four-Dimensional Transforms

幸运的是我们可以扩展向量到四维齐次坐标,并使用4×4矩阵来执行变换.对于一个3D空间中的点,多出的一个坐标称为 w 坐标其值为1.假设 M 为一个3×3矩阵, T 为一个平移向量,我们构造4×4矩阵 F 如下:

    ┌              ┐
    │M11 M12 M13 Tx│
F = │M21 M22 M23 Ty│
    │M31 M32 M33 Tz│
    │ 0   0   0  1 │
    └              ┘

用改矩阵乘 (Px, Py, Pz, 1) 与 MP+T 的结果相同, FF-1 = I4,并且将两个于 F 形式相同的矩阵相乘,可以得到相似的结果,我们可以通过此来表示旋转,位移,镜像,缩放等操作及其组合.

3.4.3 Points and Directions

点和方向向量在空间中的表现是有区别的.方向向量在平移变换中不应改改变,而点则应改变.

对于方向向量,我们把其w坐标值设为0,这样可以无视掉矩阵的平移部分.而对于点,我们将w坐标设为1,设 P 和 Q 是空间中两点, P – Q 的w坐标为0, 表示一个方向向量,从 P 指向 Q, 这也是符合期望的结果.

3.4.3 Geometrical Interpretation of the w-Coordinate

对于一个齐次空间中的向量P=(x, y, z, w), 其中 w 不为0, 对应于3D空间中的点 P’ = (x/w, y/w, z/w), 由此看出对齐次坐标进行缩放,表示的都是同一个点.

3.5 Transforming Normal Vectors

一个从属于一个多边形模型的顶点通常带有许多其它信息,比如切向量和法向量.在进行顶点位置变换时这些信息也要一起变换.切向量可以通过两个顶点的差来得到,对于转换后的切向量,用转换后的两个顶点的差计算,因此顶点位置的转换矩阵也可以正确地应用在切向量的转换上,然而对于许多非正交变换,例如缩放变换,将使法向量不再垂直于切平面.

对于切向量 T,  T’ = MT. 切向量垂直于法向量, T’ • N’ = 0, 设正确的法向量 N 的变换矩阵为 G.

N’ • T’ = (GN) • (MT) = 0
(GN) • (MT) = (GN)T(MT) = NTGTMT

因为 NTT = 0, 若 GTM = I 则 NTGTMT = 0 成立.
于是我们得到结论 G = (M-1)T.
像法向量这种向量叫协变向量,用普通方法变换的向量叫逆变向量.
若 M 是正交的, M-1 = MT, (M-1)T = M, 若我们知道 M 是正交的,就可以避免这个计算.

3.6 Quaternions 四元数

四元数是3D图形程序员用来代替旋转的一个工具,在许多方面,四元数旋转都优于矩阵,因为它需要更少的存储空间,连接四元数的计算开销也要小一些,并且易于插值来制作平滑动画.

3.6.1 Quaternion Mathematics

四元数可以看作是一个四维向量:
q = (w, x, y, z) = w + xi + yj +zk
一个四元数通常被写作 q = s + v , s表示缩放部分,代表w分量,v是一个向量,表示q的x,y,z部分.

四元数是复数的一个扩展,虚部 i,j,k 相乘时遵循以下法则:

i² = j² = k² = -1
ij = -ji = k
jk = -kj = i
ki = -ik = j

要注意它们符合乘法交换律.

设 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 = s1s2 - v1 • v2 + s1v2 + s2v1 + v1 × v2

像复数一样,四元数也有共轭,由于共轭的 q 符号打不出来,以下用 a 表示四元数, ā 为 a 的共轭, 若 a = s + v 则 ā = s – v.    a ā = ā a = a • a = ||a||² = a²

对于非0的四元数 a, 它的逆 a-1 = ā / a² , aa-1 = 1,a-1a = 1

3.6.2 Rotations with Quaternions

证明略,将 P 绕轴 A 旋转 θ 度的四元数为:

q = cos(θ/2) + Asin(θ/2)

旋转后的 P’ = qPq-1
q1( q2 P q2-1 )q1-1 = (q1q2)P(q1q2)-1

四元数对应的矩阵为:

        ┌                             ┐
        │1-2yy-2zz  2xy-2wz    2xz+2wy│
Rq(θ) = │2xy+2wz   1-2xx-2zz   2yz-2wz│
        │2xz-2wy    2yz+2wx  1-2xx-2yy│
        └                             ┘

3.6.3 Spherical Linear Interpolation

若用公式 q(t) = (1-t)q1 + tq2 进行插值,存在的问题1是插值后不能保持单位长度,需要除以 ||(1-t)q1+tq2||,另一个问题是由于三角函数不是线性的,在接近端点的位置(t=0,t=1)速度会比中间位置(t=0.5)要慢一些.

若要保持匀速,使用下面公式:

        sin[θ(1-t)]        sin(θt)
q(t) = ------------ q1 + ---------- q2
         sinθ               sinθ

其中 θ = cos-1(q1 • q2)