6.1 矩阵的行列式

对于方形矩阵,有一个特殊的标量称为矩阵的行列式(Determinant)。

6.1.1 关于2×22 \times 23×33 \times 3矩阵的行列式

方形矩阵M\mathbf{M}的行列式表示为M|\mathbf{M}|,或者“det Mdet\ \mathbf{M}”。非方形矩阵的行列式是未定义的。

二维方形矩阵行列式如下:

M=m11m12m21m22=m11m22m12m21|\mathbf{M}|=\begin{vmatrix}m_{11} & m_{12} \\ m_{21} & m_{22} \end{vmatrix}=m_{11}m_{22}-m_{12}m{21}

三维方形矩阵行列式如下:

M=m11m12m13m21m22m23m31m32m33=m11m22m33+m12m23m31+m13m21m32 m13m22m31m12m21m33m11m23m32=m11(m22m33m23m32) +m12(m23m31m21m33) +m13(m21m32m22m31)\begin{align} |\mathbf{M}| &= \begin{vmatrix} m_{11} & m_{12} & m_{13} \\ m_{21} & m_{22} & m_{23} \\ m_{31} & m_{32} & m_{33} \end{vmatrix} \\ &= m_{11}m_{22}m_{33}+m_{12}m_{23}m_{31}+m_{13}m_{21}m_{32} \\ & \quad\ -m_{13}m_{22}m_{31}-m_{12}m_{21}m_{33}-m_{11}m_{23}m_{32} \\ &= m_{11}(m_{22}m_{33} - m_{23}m_{32}) \\ & \quad\ + m_{12}(m_{23}m_{31}-m_{21}m_{33}) \\ & \quad\ + m_{13}(m_{21}m_{32}-m_{22}m_{31}) \end{align}

二维矩阵行列式助记忆
三维矩阵行列式助记

如果将3×33 \times 3矩阵的行解释为3个向量,那么该矩阵的行列式就等价于3个向量的所谓三重积。三维方形矩阵行列式与三维向量三重积如下:

axayazbxbybzcxcycz=(aybzazby)cx+(azbxaxbz)cy+(axbyaybx)cz=(a×b)c\begin{vmatrix} a_x & a_y & a_z \\ b_x & b_y & b_z \\ c_x & c_y & c_z \end{vmatrix} = \begin{matrix} (a_yb_z - a_zb_y)c_x \\ +(a_zb_x - a_xb_z)c_y \\ +(a_xb_y - a_yb_x)c_z \end{matrix} = \mathbf{(a\times b) \cdot c}

6.1.2 子矩阵行列式和余子式

子矩阵行列式(Minors)和余子式(Cofactors)之后求任意维度的行列式时会用到。

假设M\mathbf{M}是具有r列和c行的矩阵。考虑通过从M\mathbf{M}中删除行i和列j而获得矩阵。该矩阵则具有r-1行和c-1列。这个子矩阵(Submatrix)的行列式表示为Mij\mathbf{M}^{ij},被称为M\mathbf{M}的子矩阵行列式。如下表示:

M=[433022141]M12=0211=2\mathbf{M}=\begin{bmatrix}-4 & -3 & 3 \\ 0 & 2 & -2 \\ 1 & 4 & -1\end{bmatrix} \Longrightarrow \mathbf{M}^{12}=\begin{vmatrix}0 & -2 \\ 1 & -1\end{vmatrix} = 2

而余子式,是为子矩阵行列式再加上一个系数,该系数由子矩阵所删除的行列决定,则有矩阵的余子式如下表述:

Cij=(1)i+jM{ij}[++++++++]\mathbf{C}^{ij}=(-1)^{i+j}\mathbf{M}^{\{ij\}} \\ \\ \begin{bmatrix} + & - & + & - & \cdots \\ - & + & - & + & \cdots \\ + & - & + & - & \cdots \\ - & + & - & + & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix}

6.1.3 任意n×nn \times n矩阵的行列式

任意n×nn \times n矩阵的行列式计算过程如下:

  1. 任意选取一行或一列,选择哪一行或哪一列并不重要,他们都会产生相同的结果。
  2. 对这行或这列中的每一个元素,将它和它所在行列的代数余子式相乘。
  3. 将第二步中的所有结果累加。则有使用行i的余子式计算n×nn \times n行列式如下表述:

M=j=1nmijCij=j=1nmij(1)i+jM{ij}|\mathbf{M}|=\sum_{j=1}^{n}m_{ij}\mathbf{C}^{ij}=\sum_{j=1}^{n}m_{ij}(-1)^{i+j}\mathbf{M}^{\{ij\}}

如果上述公式用于4×44 \times 4的矩阵则有:

m11m12m13m14m21m22m23m24m31m32m33m34m41m42m43m44=m11m22m23m24m32m33m34m42m43m44m12m21m23m24m31m33m34m41m43m44 +m13m21m22m24m31m32m34m41m42m44m14m21m22m23m31m32m33m41m42m43\begin{align} \begin{vmatrix} m_{11} & m_{12} & m_{13} &m_{14} \\ m_{21} & m_{22} & m_{23} &m_{24} \\ m_{31} & m_{32} & m_{33} &m_{34} \\ m_{41} & m_{42} & m_{43} &m_{44} \end{vmatrix} &= m_{11}\begin{vmatrix} m_{22} & m_{23} &m_{24} \\ m_{32} & m_{33} &m_{34} \\ m_{42} & m_{43} &m_{44} \end{vmatrix} - m_{12}\begin{vmatrix} m_{21} & m_{23} &m_{24} \\ m_{31} & m_{33} &m_{34} \\ m_{41} & m_{43} &m_{44} \end{vmatrix} \\ & \quad\ + m_{13}\begin{vmatrix} m_{21} & m_{22} &m_{24} \\ m_{31} & m_{32} &m_{34} \\ m_{41} & m_{42} &m_{44} \end{vmatrix} - m_{14}\begin{vmatrix} m_{21} & m_{22} & m_{23} \\ m_{31} & m_{32} & m_{33} \\ m_{41} & m_{42} & m_{43} \end{vmatrix} \end{align}

行列式的一些重要特性:

  1. 任何维度的单位矩阵的行列式为1:I=1|\mathbf{I}|=1

  2. 矩阵乘积的行列式等于行列式的乘积:AB=AB|\mathbf{AB}|=|\mathbf{A}||\mathbf{B}|

  3. 矩阵转置的行列式等于原始行列式:MT=M|\mathbf{M^{T}}|=|\mathbf{M}|

  4. 如果矩阵中的任何行或列包含全0,则该矩阵的行列式为0:

    ??????000???=????????????=0\begin{vmatrix} ? & ? & \cdots & ? \\ ? & ? & \cdots & ? \\ \vdots & \vdots && \vdots \\ 0 & 0 & \cdots & 0 \\ \vdots & \vdots && \vdots \\ ? & ? & \cdots & ? \end{vmatrix} = \begin{vmatrix} ? & ? & \cdots & ? & \cdots & ? \\ ? & ? & \cdots & ? & \cdots & ? \\ \vdots & \vdots && \vdots && \vdots \\ ? & ? & \cdots & ? & \cdots & ? \end{vmatrix} = 0

  5. 交换任意行对(Pair Of Rows)(任意两行或两列)都会让行列式变换负:

    m11m12m1nm21m22m2nmi1mi2minmj1mj2mjnmn1mn2mnn=m11m12m1nm21m22m2nmj1mj2mjnmi1mi2minmn1mn2mnn\begin{vmatrix} m_{11} & m_{12} & \cdots & m_{1n} \\ m_{21} & m_{22} & \cdots & m_{2n} \\ \vdots & \vdots && \vdots \\ m_{i1} & m_{i2} & \cdots & m_{in} \\ \vdots & \vdots && \vdots \\ m_{j1} & m_{j2} & \cdots & m_{jn} \\ \vdots & \vdots && \vdots \\ m_{n1} & m_{n2} & \cdots & m_{nn} \end{vmatrix} =- \begin{vmatrix} m_{11} & m_{12} & \cdots & m_{1n} \\ m_{21} & m_{22} & \cdots & m_{2n} \\ \vdots & \vdots && \vdots \\ m_{j1} & m_{j2} & \cdots & m_{jn} \\ \vdots & \vdots && \vdots \\ m_{i1} & m_{i2} & \cdots & m_{in} \\ \vdots & \vdots && \vdots \\ m_{n1} & m_{n2} & \cdots & m_{nn} \end{vmatrix}

  6. 将行(列)的任意倍数添加到另一行(列)并不会更改行列式的值:

m11m12m1nm21m22m2nmi1mi2minmj1mj2mjnmn1mn2mnn=m11m12m1nm21m22m2nmi1+kmj1mi2+kmj2min+kmjnmj1mj2mjnmn1mn2mnn\begin{vmatrix} m_{11} & m_{12} & \cdots & m_{1n} \\ m_{21} & m_{22} & \cdots & m_{2n} \\ \vdots & \vdots && \vdots \\ m_{i1} & m_{i2} & \cdots & m_{in} \\ \vdots & \vdots && \vdots \\ m_{j1} & m_{j2} & \cdots & m_{jn} \\ \vdots & \vdots && \vdots \\ m_{n1} & m_{n2} & \cdots & m_{nn} \end{vmatrix} = \begin{vmatrix} m_{11} & m_{12} & \cdots & m_{1n} \\ m_{21} & m_{22} & \cdots & m_{2n} \\ \vdots & \vdots && \vdots \\ m_{i1}+km_{j1} & m_{i2}+km_{j2} & \cdots & m_{in}+km_{jn} \\ \vdots & \vdots && \vdots \\ m_{j1} & m_{j2} & \cdots & m_{jn} \\ \vdots & \vdots && \vdots \\ m_{n1} & m_{n2} & \cdots & m_{nn} \end{vmatrix}

  1. 错切矩阵的行列式为1。

6.1.4 行列式的几何解释

在二维中,行列式等于具有基向量作为两条边的平行四边形或倾斜框(Skew Box)的有符号面积。如图:

二维中的行列式是由变换的基向量形成的倾斜框的有符号区域

同理,在三维中,行列式是有3个基向量作为边的平行六面体的体积。如果对象经过变换被反射,行列式为负。

行列式与矩阵变换导致的大小变化有关。行列式的绝对值表示了一个变换是否改变了多个向量所构成物体的面积或体积,行列式的符号则表示在矩阵中是否包含任何反射或投影。如果矩阵行列式为零,则该矩阵包含投影;如果矩阵的行列式是负的,那么矩阵中包含了反射。

6.2 逆矩阵

仅适用于方形矩阵运算的另一个矩阵。方形矩阵M\mathbf{M}的逆矩阵,表示为M1\mathbf{M^{-1}},矩阵与逆矩阵的乘积为单位矩阵。即:M(M1)=M1M=I\mathbf{M(M^{-1})=M^{-1}M=I}

并不是所有矩阵都有逆矩阵(如:一个行或列填充0的矩阵——无论乘以什么,结果中相应的行或列都是满0)。如果某个矩阵具有逆矩阵,则称为可逆矩阵或非奇异矩阵,反之称为不可逆矩阵或奇异矩阵。

对于可逆矩阵有如下性质:

  1. 对于任何可逆矩阵,当前仅当v=0\mathbf{v=0}时有vM=0\mathbf{vM=0}
  2. 任何可逆矩阵的行和列都是线性不相关的。
  3. 可逆矩阵的行列式不为0。因此检查一个矩阵的行列式是否为零是最通用且最快的检查矩阵是否可逆的方法。

6.2.1 伴随矩阵

伴随矩阵(Classical Adjoint)是计算逆矩阵的方法。将矩阵M\mathbf{M}的伴随矩阵称为“adj Madj \ \mathbf{M}”。

伴随矩阵是原矩阵所有代数余子式构成的矩阵的转置。如下以一个3×33 \times 3矩阵M\mathbf{M}作为例子:

M=[433022141]\mathbf{M}=\begin{bmatrix}-4&-3&3\\0&2&-2\\1&4&-1\end{bmatrix}

要求伴随矩阵,则需要求出所有的余子式:

C{11}=+2241=6,C{12}=0211=2,C{13}=+0214=2,C{21}=3341=9,C{22}=+4311=1,C{23}=4314=13,C{31}=+3322=0,C{32}=4402=8,C{33}=+4402=8,\begin{align} &\mathbf{C}^{\{11\}}=+\begin{vmatrix}2&-2\\4&-1\end{vmatrix}=6, \mathbf{C}^{\{12\}}=-\begin{vmatrix}0&-2\\1&-1\end{vmatrix}=-2, \mathbf{C}^{\{13\}}=+\begin{vmatrix}0&2\\1&4\end{vmatrix}=-2, \\ &\mathbf{C}^{\{21\}}=-\begin{vmatrix}-3&3\\4&-1\end{vmatrix}=9, \mathbf{C}^{\{22\}}=+\begin{vmatrix}-4&3\\1&-1\end{vmatrix}=1, \mathbf{C}^{\{23\}}=-\begin{vmatrix}-4&-3\\1&4\end{vmatrix}=13, \\ &\mathbf{C}^{\{31\}}=+\begin{vmatrix}-3&3\\2&-2\end{vmatrix}=0, \mathbf{C}^{\{32\}}=-\begin{vmatrix}-4&4\\0&-2\end{vmatrix}=-8, \mathbf{C}^{\{33\}}=+\begin{vmatrix}-4&4\\0&2\end{vmatrix}=-8, \end{align}

伴随矩阵如下:

adj M=[C{11}C{12}C{13}C{21}C{22}C{23}C{31}C{32}C{33}]T=[6229113088]T=[6902182138]\begin{align} adj \ \mathbf{M} &= \begin{bmatrix} \mathbf{C}^{\{11\}} & \mathbf{C}^{\{12\}} & \mathbf{C}^{\{13\}} \\ \mathbf{C}^{\{21\}} & \mathbf{C}^{\{22\}} & \mathbf{C}^{\{23\}} \\ \mathbf{C}^{\{31\}} & \mathbf{C}^{\{32\}} & \mathbf{C}^{\{33\}} \end{bmatrix} ^T \\ &= \begin{bmatrix} 6 & -2 & -2 \\ 9 & 1 & 13 \\ 0 & -8 & -8 \end{bmatrix} ^T = \begin{bmatrix} 6 & 9 & 0 \\ -2 & 1 & -8 \\ -2 & 13 & -8 \end{bmatrix} \end{align}

6.2.2 正式线性代数规则

用矩阵的伴随矩阵除以矩阵的行列式,即为矩阵的逆矩阵。因为计算逆矩阵时要除以矩阵的行列式,所以行列式为0的矩阵是不存在逆矩阵的。公式如下:

M1=adj MM\mathbf{M}^{-1}=\frac{adj\ \mathbf{M}}{\mathbf{|M|}}

高斯消除法的运算量会更小,但针对图形学最常用的3×33 \times 34×44 \times 4大小的矩阵,用伴随矩阵的方法就已经足够。

矩阵求逆有以下几个特性:

  1. 矩阵的逆矩阵的逆是原始矩阵:(M1)1=M(假设M是非奇异的)\mathbf{(M^{-1})^{-1}=M}\quad(假设\mathbf{M}是非奇异的)
  2. 单位矩阵是它自己的逆:I1=I\mathbf{I^{-1}=I}。单位矩阵并不是唯一的逆矩阵为本身的矩阵,反射矩阵和旋转180°的矩阵也满足。
  3. 矩阵转置的逆矩阵是逆矩阵的转置:(MT)1=(M1)T\mathbf{(M^T)^{-1}=(M^{-1})^T}
  4. 矩阵乘积等于相反顺序矩阵的逆的乘积:(AB)1=B1A1\mathbf{(AB)^{-1}=B^{-1}A^{-1}}
  5. 逆矩阵的行列式是原始矩阵的行列式的倒数:M1=1M\mathbf{|M^{-1}|=\frac{1}{|M|}}

6.2.4 几何解释

逆矩阵在几何中可以计算变换的“反向”或“相反”。如果它们按顺序执行,则意味着一个变换“撤销”另一个变换。代数验证如下:

(vM)M1=v(MM1)=vI=v\mathbf{(vM)M^{-1}=v(MM^{-1})=vI=v}

6.3 正交矩阵

6.3.1 正式线性代数规则

当且仅当矩阵及其转置的乘积是单位矩阵时,方形矩阵M\mathbf{M}是正交的。如:

M是正交矩阵MMT=I\mathbf{M}是正交矩阵 \quad \Longleftrightarrow \quad \mathbf{MM^T=I}

因为矩阵乘以其逆矩阵的乘积是单位矩阵(MM1=I\mathbf{MM^{-1}=I}),则其矩阵和逆矩阵也是相等的。如:

M是正交矩阵MT=M1\mathbf{M}是正交矩阵 \quad \Longleftrightarrow \quad \mathbf{M^T=M^{-1}}

如果知道一个矩阵是正交的(如旋转和反射变换),那么可以很快的通过求其转置矩阵来获得逆矩阵

6.3.2 几何解释

正交矩阵的意义在于其逆矩阵非常容易求得(转置矩阵即为逆矩阵)。如果一个变换仅包含位移,旋转和反射,那么它为正交矩阵。如果一个矩阵的每一行(或每一列)构成的基本向量长度为1,且相互垂直,那么它也是正交矩阵。

假设M\mathbf{M}3×33 \times 3矩阵。则有

MMT= I,[m11m12m13m21m22m23m31m32m33][m11m21m31m12m22m32m13m23m33]=[100010001]\begin{align} \mathbf{M} \quad\quad\quad\quad\quad\quad\quad \mathbf{M^T} \quad\quad\quad &= \quad\quad\ \mathbf{I},\\ \begin{bmatrix} m_{11} & m_{12} & m_{13} \\ m_{21} & m_{22} & m_{23} \\ m_{31} & m_{32} & m_{33} \end{bmatrix} \begin{bmatrix} m_{11} & m_{21} & m_{31} \\ m_{12} & m_{22} & m_{32} \\ m_{13} & m_{23} & m_{33} \end{bmatrix} &= \begin{bmatrix} 1&0&0\\ 0&1&0\\ 0&0&1 \end{bmatrix} \end{align}

用向量r1r2r3\mathbf{r_1、r_2、r3}代表M\mathbf{M}的行:

r1=[m11m12m13],r2=[m21m22m23],r3=[m31m32m33],M=[r1r2r3]\begin{align} \mathbf{r_1}&=\begin{bmatrix}m_{11} & m_{12} & m_{13}\end{bmatrix},\\ \mathbf{r_2}&=\begin{bmatrix}m_{21} & m_{22} & m_{23}\end{bmatrix},\\ \mathbf{r_3}&=\begin{bmatrix}m_{31} & m_{32} & m_{33}\end{bmatrix},\\ \mathbf{M}&=\begin{bmatrix}r_1 \\ r_2 \\ r_3 \end{bmatrix} \end{align}

可以获得正交矩阵满足的条件:

r1r1=1,r1r2=0,r1r3=0,r2r1=0,r2r2=1,r2r3=0,r3r1=0,r3r2=0,r3r3=1,\mathbf{r_1 \cdot r_1}=1,\quad\quad \mathbf{r_1 \cdot r_2}=0,\quad\quad\mathbf{r_1 \cdot r_3}=0,\\ \mathbf{r_2 \cdot r_1}=0,\quad\quad \mathbf{r_2 \cdot r_2}=1,\quad\quad\mathbf{r_2 \cdot r_3}=0,\\ \mathbf{r_3 \cdot r_1}=0,\quad\quad \mathbf{r_3 \cdot r_2}=0,\quad\quad\mathbf{r_3 \cdot r_3}=1,

当且仅当向量是单位向量是,向量与自身的点积才为1。当且仅当两个向量垂直时,他们的点积才为0。所以要使矩阵正交,必须满足:矩阵的每一行都是单位向量,矩阵的行必须相互垂直。如果一个矩阵是正交的,那么它的转置也必然是正交的。

这里需要进行一项很重要的专业说明,因为它可能会让人有点困惑。在线性代数中,如果一组基矢量相互垂直,则将它们描述为正交 ( Orthogonal)。它们不需要具有单位长度。如果它们确实具有单位长度,则它们是标准正交基 ( Orthonormal Basis)。因此,正交矩阵( Orthogonal Matrix) 的行和列是标准正交基矢量(Orthonormal Basis Vector)。然而,从一组正交基矢量构造矩阵不一定导致正交矩阵(除非基矢量也是标准正交基 )。

6.3.3 矩阵的正交化

我们可能会遇到一些略微偏离正交性的矩阵。这可能是因为外部资源获取了不良数据,或者可能积累了浮点误差,后者称为矩阵蠕变(Matrix Creep)。对于用于凹凸映射(Bump Mapping)的基向量,通常会将基向量调整为正交,即使纹理映射渐变不是很垂直。这些情况下,我们都希望对矩阵进行正交化(Orthogonalize),从而得到一个矩阵,该矩阵具有相互垂直的单位向量轴,并且尽可能的接近原始矩阵。

用于构造一组正交基向量(它是正交矩阵的行)的标准算法是Gram-Schmidt正交化。其基本思想是按顺序遍历基向量。对于每个基向量,我们将减去与基向量平行的向量,这必然会产生垂直向量。

首先将矩阵的标准向量(每一行)定义为r1r2r3\mathbf{r_1、r_2、r_3},并将转换后的满足相互垂直的基本向量定义为r1r2r3\mathbf{r_1^{'}、r_2^{'}、r_3^{'}}。则三维基向量的Gram-Schmidt正交化如下表述:

r2r1,r2r2r2r1r1r1r1,r3r3r3r1r1r1r1r3r2r2r2r2,\begin{align} \mathbf{r_2^{'}} &\Leftarrow \mathbf{r_1}, \\ \mathbf{r_2^{'}} &\Leftarrow \mathbf{r_2-\frac{r_2\cdot r_1^{'}}{r_1^{'}\cdot r_1^{'}}r_1^{'}}, \\ \mathbf{r_3^{'}} &\Leftarrow \mathbf{r_3-\frac{r_3\cdot r_1^{'}}{r_1^{'}\cdot r_1^{'}}r_1^{'} - \frac{r_3\cdot r_2^{'}}{r_2^{'}\cdot r_2^{'}}r_2^{'}}, \end{align}

其中r2\mathbf{r_2^{'}}只所以这么定义,是为了从r2\mathbf{r_2}中减去平行于r1\mathbf{r_1}的部分,这样剩余部分r2\mathbf{r_2^{'}}即为垂直于r1\mathbf{r_1}的部分。且根据利用点乘求向量分量的定义可得:

r2=r2(r2r1^)r1^=r2(r2r1r1)r1r1=r2r2r1r12r1=r2r2r1r1r1r1\begin{align} \mathbf{r_2^{'}} &= \mathbf{r_2-(r_2\cdot \hat{r_1})\cdot \hat{r_1}} \\ &= \mathbf{r_2-(r_2\cdot \frac{r_1^{'}}{|r_1|})\cdot \frac{r_1^{'}}{|r_1|}} \\ &= \mathbf{r_2-\frac{r_2\cdot r_1^{'}}{|r_1|^2}\cdot r_1^{'}} \\ &= \mathbf{r_2-\frac{r_2\cdot r_1^{'}}{r_1^{'}\cdot r_1^{'}}r_1^{'}} \end{align}

r3\mathbf{r_3^{'}}的过程同理的推导。但是对于r3\mathbf{r_3^{'}}还可以通过r1r2\mathbf{r_1^{'}、r_2^{'}}获得,即:r3r1×r2\mathbf{r_3^{'} \Leftarrow r_1^{'}\times r_2^{'}}

Gram-Schmidt算法是有偏差的,这取决于列出的基向量的顺序(r1r_1永远不会改变,而r3r_3可能会改变很多)。该算法的一次迭代将产生一组比原始向量稍微“更正交”的一些基向量,但不可能完全正交。通过多次重复过程,我们最终可以在正交基向量上收敛,为k选择一个适当小的值并迭代足够多次会让我们相当接近正交,然后可以用标准的Gram-Schmidt算法来保证获取完全正交基。

r1r1kr1r2r2r2r2kr1r3r3r3r3,r2r2kr2r1r1r1r1kr2r3r3r3r3,r3r3kr3r1r1r1r1kr3r2r2r2r2\begin{align} \mathbf{r_1^{'}} &\Leftarrow \mathbf{r_1-k\frac{r_1\cdot r_2}{r_2\cdot r_2}r_2 - k\frac{r_1\cdot r_3}{r_3\cdot r_3}r_3}, \\ \mathbf{r_2^{'}} &\Leftarrow \mathbf{r_2-k\frac{r_2\cdot r_1}{r_1\cdot r_1}r_1 - k\frac{r_2\cdot r_3}{r_3\cdot r_3}r_3}, \\ \mathbf{r_3^{'}} &\Leftarrow \mathbf{r_3-k\frac{r_3\cdot r_1}{r_1\cdot r_1}r_1 - k\frac{r_3\cdot r_2}{r_2\cdot r_2}r_2} \end{align}

Gram-Schmidt正交化是一种将线性无关的向量组转化为正交向量组的方法。其基本思想是通过一个迭代的过程,将原向量组中的每个向量分解为一组正交向量的线性组合,从而得到一个正交的向量组。

设有线性无关向量组 v1,v2,...,vnv_1,v_2,...,v_n,则Gram-Schmidt正交化的步骤如下:

  1. u1=v1u_1 = v_1,即将第一个向量保持不变。

  2. 对于 i=2,3,...,ni=2,3,...,n,执行以下步骤:

    a. 计算第 ii 个向量 viv_i 在前面所有向量的投影和:

    projuj(vi)=viujujujuj    (j=1,2,...,i1)proj_{u_{j}}(v_i)=\frac{v_i\cdot u_{j}}{u_j\cdot u_j}u_j\ \ \ \ (j=1,2,...,i-1)

    b. 令 ui=viu_i = v_i 减去前面所有向量的投影和:

    ui=vij=1i1projuj(vi)u_i=v_i-\sum_{j=1}^{i-1} proj_{u_{j}}(v_i)

    c. 对于 uiu_i,进行单位化处理,得到正交向量:

    ei=uiuie_i=\frac{u_i}{||u_i||}

  3. 重复步骤 2 直到处理完所有的向量。

最终得到的向量组 e1,e2,...,ene_1,e_2,...,e_n 是一个正交向量组,且与原向量组张成同一个线性空间。

需要注意的是,在计算投影时,分母为 ujuju_j\cdot u_j,如果分母为 0,则无法进行计算。因此,在进行计算之前,需要确保前面所有向量都不是线性相关的,以避免出现这种情况。

公式 projuj(vi)=viujujujujproj_{u_j}(v_i)=\frac{v_i\cdot u_j}{u_j\cdot u_j}u_j 表示将向量 viv_i 在向量 uju_j 上的投影。具体来说,分子 viujv_i\cdot u_j 表示向量 viv_i 与向量 uju_j 的点积,分母 ujuju_j\cdot u_j 表示向量 uju_j 的模长的平方,因此 viujujuj\frac{v_i\cdot u_j}{u_j\cdot u_j} 表示向量 viv_i 在向量 uju_j 上的投影长度。

得到投影长度之后,将其乘以向量 uju_j 的单位向量 uj/uju_j/|u_j| 即可得到向量 viv_i 在向量 uju_j 上的投影向量,即 projuj(vi)=viujujujuj=viujuj2ujujproj_{u_j}(v_i)=\frac{v_i\cdot u_j}{u_j\cdot u_j}u_j=\frac{v_i\cdot u_j}{|u_j|^2}\frac{u_j}{|u_j|}

这里的 ujuj\frac{u_j}{|u_j|} 表示向量 uju_j 的单位向量,将投影向量乘以单位向量可以得到向量 viv_i 在向量 uju_j 上的投影向量。

来自ChatGPT的回答。

6.4 关于4×44 \times 4齐次矩阵

这部分第一次提及了四维向量,称为齐次坐标(Homogeneous coordinate)。

6.4.1 关于思维齐次空间

为了更好的理解物理的三维空间是如何扩展到四维空间的。先以二维空间为例,想象二维空间是存在于三维齐次空间中的一个平面,且第三个元素值为1,即w=1w=1,所有在该平面上的点都可表示为(x,y,1)(x,y,1)。所有不在w=1w=1平面上的齐次坐标点(x,y,w)(x,y,w),都可以通过(x/w,y/w,1)(x/w,y/w,1)转换到二维物理平面上。如下:

将齐次坐标投影到二维中的平面

对于任何在二维平面上的点(x,y)(x,y)都有无限多个相应的在齐次坐标中的点(kx,ky,k)(kx,ky,k)。这些点构成一条穿越原点的直线。

w=0w=0时,除法是未定义的,所以没有相对应的在二维物理平面上的点。因此将w=0的坐标定义为是在无限远处的点,这些点是用来表示方向而不是位置,即w=0w=0的坐标实际上是作为向量来进行处理,而w0w\neq0的点才是作为表示位置的点。

将二维空间的概念推广到三维空间中,三维空间中的点也同样可以看作是在四维齐次空间中,只不过第四个元素值w=1w=1。同样的,任意在四维齐次空间中的点,都可以通过(x/w,y/w,z/w,1)(x/w,y/w,z/w,1)转换到三维空间中。当w=0w=0时,坐标同样是用来表示向量而不是点。

在三维空间中引入四维齐次坐标主要有两个原因:

  1. 为了计算上的便捷,因为位移需要用到四维矩阵,而将其他所有的变形都用四维矩阵表示可以方便计算。
  2. 第四个参数ww可以用于表示透视投影(perspective projection)。

6.4.2 关于4×44 \times 4平移矩阵

因为nn维零向量与任何的n×nn \times n矩阵相乘结果都是nn维零向量,所以通过一个3×3的矩阵是永远无法将一个点从原点移动出去的,即nn维的矩阵无法在nn维空间中表示位移。

但是可以通过一个4×44 \times 4的矩阵在三维空间中表示位移。如下所示:

[xyz1][100001000010ΔxΔyΔz1]=[x+Δxy+Δyz+Δz1]\begin{bmatrix}x&y&z&1\end{bmatrix} \begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ \Delta{x}&\Delta{y}&\Delta{z}&1 \end{bmatrix} = \begin{bmatrix} x+\Delta{x}&y+\Delta{y}&z+\Delta{z}&1 \end{bmatrix}

注意这个变换在四维空间中,仍然是一个线性变换(具体来说是切变),但从三维空间角度来看,就是一个仿射变换,对三维向量进行了位移。

另外三维矩阵可以扩展成四维矩阵来表示普通的三维向量的变换,如下所示:

[xyz1][m11m12m130m21m22m230m31m32m3300001]=[xm11+ym21+zm31xm12+ym22+zm32xm13+ym23+zm331]\begin{bmatrix}x&y&z&1\end{bmatrix} \begin{bmatrix} m_{11} & m_{12} & m_{13} & 0 \\ m_{21} & m_{22} & m_{23} & 0 \\ m_{31} & m_{32} & m_{33} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\\ = \begin{bmatrix} xm_{11}+ym_{21}+zm_{31} & xm_{12}+ym_{22}+zm_{32} & xm_{13}+ym_{23}+zm_{33} & 1 \end{bmatrix}

因此,如果一个三维向量需要先进行旋转变换(变换矩阵为R\mathbf{R}),再进行位移变换(位移矩阵为T\mathbf{T}),则矩阵及表达式如下:

R=[r11r12r130r21r22r230r31r32r3300001],T=[100001000010ΔxΔyΔz1]\mathbf{R}=\begin{bmatrix} r_{11} & r_{12} & r_{13} & 0 \\ r_{21} & r_{22} & r_{23} & 0 \\ r_{31} & r_{32} & r_{33} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix},\quad \mathbf{T}=\begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ \Delta{x}&\Delta{y}&\Delta{z}&1 \end{bmatrix}

然后先旋转再平移点v\mathbf{v}来计算v\mathbf{v^{'}},其公式为:v=vRT\mathbf{v^{'}=vRT}。我们把两个矩阵连接成单个矩阵M\mathbf{M},则有M=RT\mathbf{M=RT}。则有:

v=vRT=v(RT)=vM\mathbf{v^{'}=vRT=v(RT)=vM}

则有M\mathbf{M}的表述如下:

M=RT=[r11r12r130r21r22r230r31r32r3300001][100001000010ΔxΔyΔz1]=[r11r12r130r21r22r230r31r32r330ΔxΔyΔz1]\begin{align} \mathbf{M}=\mathbf{RT}&= \begin{bmatrix} r_{11} & r_{12} & r_{13} & 0 \\ r_{21} & r_{22} & r_{23} & 0 \\ r_{31} & r_{32} & r_{33} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ \Delta{x}&\Delta{y}&\Delta{z}&1 \end{bmatrix} \\ &= \begin{bmatrix} r_{11} & r_{12} & r_{13} & 0 \\ r_{21} & r_{22} & r_{23} & 0 \\ r_{31} & r_{32} & r_{33} & 0 \\ \Delta{x}&\Delta{y}&\Delta{z}&1 \end{bmatrix} \end{align}

可以看出M\mathbf{M}上面的3×33 \times 3部分包含旋转部分,底下的行包含的事平移部分,最右边的列[0001]T\begin{bmatrix}0&0&0&1\end{bmatrix}^T。我们可以用块矩阵表示法(Block Matrix Notation)来表示M\mathbf{M},将平移向量[ΔxΔyΔz]\begin{bmatrix}\Delta{x}&\Delta{y}&\Delta{z}\end{bmatrix}指定给向量t\mathbf{t},则有如下表述:

M=[M0t1]\mathbf{M}=\begin{bmatrix}\mathbf{M}&0\\ \mathbf{t}&1\end{bmatrix}

另外如前所述,当一个齐次空间中的向量坐标的第四个元素w=0w=0时,这个坐标表示的是位置而不是位移,这就是所谓的“无限远的点”,如下所示,取向量的坐标为[xyz0]\begin{bmatrix}x&y&z&0\end{bmatrix},与M\mathbf{M}相乘的结果将不包含位移信息,如:

[xyz0][m11m12m130m21m22m230m31m32m330ΔxΔyΔz1]=[xm11+ym21+zm31xm12+ym22+zm32xm13+ym23+zm330]\begin{bmatrix}x&y&z&0\end{bmatrix} \begin{bmatrix} m_{11} & m_{12} & m_{13} & 0 \\ m_{21} & m_{22} & m_{23} & 0 \\ m_{31} & m_{32} & m_{33} & 0 \\ \Delta{x}&\Delta{y}&\Delta{z}&1 \end{bmatrix}\\ = \begin{bmatrix} xm_{11}+ym_{21}+zm_{31} & xm_{12}+ym_{22}+zm_{32} & xm_{13}+ym_{23}+zm_{33} & 0 \end{bmatrix}

6.4.3 一般仿射变换

在四维齐次空间中,就能实现仿射变换而不仅仅是线性变换,经常使用的仿射变换包括:

  • 围绕不穿过原点的轴旋转。
  • 围绕不穿过原点的平面进行缩放。
  • 围绕不穿过原点的平面反射。
  • 在不穿过原点的平面上进行正交投影。

这里的基本思想是将变换的“中心”平移到原点,然后再进行线性变换,左后平移会原始位置。将位移矩阵命名为T\mathbf{T},将线性变换的矩阵命名为R\mathbf{R},仿射变换矩阵命名为A\mathbf{A},与T\mathbf{T}具有相反平移量的平移矩阵命名为T1\mathbf{T^{-1}},则有:

T=[100001000010pxpypz1]=[I0p1];R4×4=[r11r12r130r21r22r230r31r32r3300001]=[R001];T1=[100001000010pxpypz1]=[I0p1];A=TR4×4T1=[I0p1][R3×3001][I0p1]=[R3×30p(R3×3)1][I0p1]=[R3×30p(R3×3)+p1]\begin{align} \mathbf{T}&=\begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ -p_x&-p_y&-p_z&1 \end{bmatrix} =\begin{bmatrix} \mathbf{I}&0\\ \mathbf{-p}&1 \end{bmatrix}; \\ \mathbf{R_{4 \times 4}} &= \begin{bmatrix} r_{11} & r_{12} & r_{13} & 0 \\ r_{21} & r_{22} & r_{23} & 0 \\ r_{31} & r_{32} & r_{33} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} \mathbf{R}&0\\ 0&1 \end{bmatrix}; \\ \mathbf{T^{-1}}&=\begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ p_x&p_y&p_z&1 \end{bmatrix} =\begin{bmatrix} \mathbf{I}&0\\ \mathbf{p}&1 \end{bmatrix}; \\ \\ \mathbf{A} &=\mathbf{TR_{4\times4}T^{-1}}= \begin{bmatrix} \mathbf{I}&0\\ \mathbf{-p}&1 \end{bmatrix} \begin{bmatrix} \mathbf{R_{3\times3}}&0\\ 0&1 \end{bmatrix} \begin{bmatrix} \mathbf{I}&0\\ \mathbf{p}&1 \end{bmatrix} \\ &= \begin{bmatrix} \mathbf{R_{3\times3}}&0 \\ \mathbf{-p(R_{3\times3})}&1 \end{bmatrix} \begin{bmatrix} \mathbf{I}&0\\ \mathbf{p}&1 \end{bmatrix} \\ &= \begin{bmatrix} \mathbf{R_{3\times3}}&0 \\ \mathbf{-p(R_{3\times3})+p}&1 \end{bmatrix} \end{align}

6.5 关于4×44 \times 4矩阵和透视投影

在第五章中提到了正交投影,正交投影是一种平行投影,每条顶点和其投影点的连线是平行的,如下:

正交投影使用平行投影线

三维中的透视投影也投影到二维平面上,但是,投影并不平行。它们在一个点上相交,这个点称为投影中心(Center Of Projection)。由于投影中心位于投影的前方,投影线在撞击平面之前交叉,因此图像被反转。对于一个透视投影来说,投影平面是固定的,投影中心距离投影平面的距离也是固定的,因此物体离投影中心越近,其在投影平面上的构成的图像大小就越大,这个现象称为透视收缩(Perspective Forshortening)。

6.5.1 针孔相机

透视投影之所以在图形学中很重要,是因为它就是人类视觉系统工作的方式。人眼可以简化为是一个小孔成像系统,如下所示:

针孔相机

小口成像可以用坐标来表示,将投影看作是原点,将物体的顶点看作是pp点,将物体在投影平面上的成像看作是pp′,如下侧视图所示:

从侧面看投影平面

根据三角形相似定理,可得:

pyd=pyzpy=dpyz\frac{-p_y^{'}}{d}=\frac{p_y}{z} \Longrightarrow p_y^{'}=\frac{-dp_y}{z}

同理可得:

px=dpxzp_x^{'}=\frac{-dp_x}{z}

所有投影点的zz值都相同:d-d。因此,将点pp通过原点投影到z=dz=-d的平面上的结果是:

p=[xyz]p=[xyz]=[dx/zdy/zd]p=\begin{bmatrix}x&y&z\end{bmatrix} \quad \Longrightarrow \quad p^{'}=\begin{bmatrix}x^{'}&y^{'}&z^{'}\end{bmatrix} =\begin{bmatrix} -dx/z & -dy/z & -d\end{bmatrix}

在计算机的实际运用中,上述结果中的负号是完全没意义的,因此可以等同于将投影平面移动到投影中心前面(这样的作法在真实物理世界中是不可行的),如下图:

在投影中心前面投影平面

则变换为:

p=[xyz]=[dx/zdy/zd]p^{'}=\begin{bmatrix}x^{'}&y^{'}&z^{'}\end{bmatrix} =\begin{bmatrix} dx/z & dy/z & d\end{bmatrix}

6.5.2 透视投影矩阵

因为从思维到三维空间的转换意味着除法,所以可以在4×44 \times 4矩阵中编码透视投影。其基本思量是为pp^{'}xyx、yzz的公分母提出一个等式,然后设置一个4×44 \times 4矩阵,将ww设置为等于这个分母。

p=[dx/zdy/zd]=[dx/zdy/zdz/z]=[xyz]z/dp^{'} =\begin{bmatrix} dx/z & dy/z & d\end{bmatrix}= \begin{bmatrix} dx/z & dy/z & dz/z\end{bmatrix}=\frac{[x \quad y \quad z]}{z/d}

公因数为z/dz/d,因此我们将该分母放入ww中,可以获得齐次坐标:[xyzz/d]\begin{bmatrix}x&y&z&z/d\end{bmatrix}

所以我们需要一个4×44 \times 4矩阵,它将乘以一个齐次向量[xyz1]\begin{bmatrix}x&y&z&1\end{bmatrix}以产生[xyzz/d]\begin{bmatrix}x&y&z&z/d\end{bmatrix}。则有:

[xyz1][100001000011/d0000]=[xyzz/d]\begin{bmatrix}x&y&z&1\end{bmatrix} \begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&1/d\\ 0&0&0&0 \end{bmatrix} =\begin{bmatrix}x&y&z&z/d\end{bmatrix}

此矩阵的乘法并不是真正执行透视变换,它只是计算恰当的分母给ww当通过除以ww将四维转换为三维时,就会真正执行透视除法。

在真实运用中,投影矩阵会比这里更加复杂(同样也会称为裁剪矩阵),主要的区别在于:

  1. 大多数图形系统应用归一化的比例因子,使得在远端剪辑平面处w=1w=1。这确保了用于深度缓冲的值适用于正被渲染的场景,以最大化深度缓冲的精度。
  2. 大多数图形系统中的投影矩阵还会根据相机的视野缩放xxyy值。

深度缓存是一种基于物体与相机之间距离的技术,用于决定哪些物体应该在场景中可见。为了实现这一目的,渲染图像中的每个像素都被分配一个深度值,其基于其与相机的距离。

然而,由于场景中的距离范围可以有很大的差异,深度值分布可能不均匀,也可能不如所需的那样精确,从而影响了渲染的精度。为了解决这个问题,在深度渲染时应用了一个归一化缩放因子,以使深度值更加均匀地分布,并在离相机最远的位置(远截面)处获得更高的精度。

通过应用这个缩放因子,深度值被调整以更好地匹配场景中的距离范围,从而提高了深度缓存的精度,确保物体之间的渲染正确无误。


引用:

  1. Dunn, F. and Parberry, I. (2011). 3D math primer for graphics and game development 2nd2^{nd}.