矩阵的行列式
在任意方阵中都存在一个标量,称作该方阵的行列式。
线性运算法则
方阵M的行列式记作|M|或“det M”,非方阵矩阵的行列式是未定义的。n x n阶矩阵的行列式定义非常复杂,让我们先从2 x 2,3 x 3矩阵开始。
公式9.1给出了2 x 2阶矩阵行列式的定义:
注意,在书写行列式时,两边用竖线将数字块围起来,省略方括号。
下面的示意图能帮助记忆公式9.1,将主对角线和反对角线上的元素各自相乘,然后用主对角线元素的积减去反对角线元素的积。
3 x 3 阶矩阵的行列式定义如公式9.2所示:
可以用类似的示意图来帮助记忆。把矩阵M连写两遍,将主对角线上的元素和反对角线上的元素各自相乘,然后用各主对角线上元素积的和减去各反对角线上元素积的和。
如果将3 x 3阶矩阵的行解释为3个向量,那么矩阵的行列式等于这些向量的所谓“三元组积”。
假设矩阵M有r行c列,记法M{ij}表示从M中除去第i行和第j列后剩下的矩阵。显然,该矩阵有r-1行,c-1列,矩阵M{ij}称作M的余子式。
对方阵M,给定行、列元素的代数余子式等于相应余子式的有符号行列式,见公式9.3:
如上,用记法cij表示M的第i行,第j列元素的代数余子式。注意余子式是一个矩阵,而代数余子式是一个标量。代数余子式计算式中的项(–1)(i+j)有以棋盘形式使矩阵的代数余子式每隔一个为负的效果:
n维方阵的行列式存在着多个相等的定义,我们可以用代数余子式来定义矩阵的行列式(这种定义是递归的,因为代数余子式本身的定义就用到了矩阵的行列式)。
首先,从矩阵中任意选择一行或一列,对该行或列中的每个元素,都乘以对应的代数余子式。这些乘积的和就是矩阵的行列式。例如,任意选择一行,如行i,行列式的计算过程如公式9.4所示:
下面举一个例子,重写3x3矩阵的行列式:
综上,可导出4x4矩阵的行列式:
高阶行列式计算的复杂性是呈指数递增的。幸运的是,有一种称作”主元选择“的计算方法,它不影响行列式的值,但它能使特定的行或列中除了一个元素(主元)外其他元素全为0,这样仅一个代数余子式需要计算。
行列式的一些重要性质:
(1)矩阵积的行列式等于矩阵行列式的积:|AB| = |A||B|
这可以扩展到多个矩阵: |M1 M2 ... Mn| = |M1| |M2| ... |Mn-1| |Mn|
(2)矩阵转置的行列式等于原矩阵的行列式:|MT| = |M|
(3)如果矩阵的任意行或列全为0,那么它的行列式等于0.
(4)交换矩阵的任意两行或两列,行列式变负。
(5)任意行或列的非零积加到另一行或列上不会改变行列式的积。
几何解释
矩阵的行列式有着非常有趣的几何解释。2D中,行列式等于以基向量为两边的平行四边形的有符号面积(如图9.1所示)。有符号面积是指如果平行四边形相对于原来的方位”翻转“,那么面积变负。
3D中,行列式等于以变换后的基向量为三边的平行六面体的有符号的体积。3D中,如果变换使得平行六面体”有里向外“翻转,则行列式变负。
行列式与矩阵变换导致的尺寸改变相关,其中行列式的绝对值与面积(2D)、体积(3D)的改变相关,行列式的符号说明了变换矩阵是否包含镜像或投影。
矩阵的行列式还能对矩阵所代表的变换进行分类。如果矩阵的行列式为0,那么该矩阵包含投影。如果矩阵的行列式为负,那么该矩阵包含镜像。
矩阵的逆
另外一种重要的矩阵运算是矩阵的求逆,这个运算只能用于方阵。
运算法则
方阵M的逆,记作M-1,也是一个矩阵。当M与M-1相乘时,结果是单位矩阵。表示为公式9.6的形式:
并非所有的矩阵都有逆。一个明显的例子是若矩阵的某一行或列上的元素都为0,用任何矩阵乘以该矩阵,结果都是一个零矩阵。如果一个矩阵有逆矩阵,那么称它 为可逆的或非奇异的。如果一个矩阵没有逆矩阵,则称它为不可逆的或奇异矩阵。奇异矩阵的行列式为0,非奇异矩阵的行列式不为0,所以检测行列式的值是判断 矩阵是否可逆的有效方法。此外,对于任意可逆矩阵M,当且仅当v=0时,vM=0。
M的”标准伴随矩阵“记作”adjM“,定义为M的代数余子式矩阵的转置矩阵。下面是一个例子,考虑前面给出的3x3阶矩阵M:
计算M的代数余子式矩阵:
M的标准伴随矩阵是代数余子式矩阵的转置:
一旦有了标准伴随矩阵,通过除以M的行列式,就能计算矩阵的逆。
其表示如公式9.7所示:
例如为了求得上面矩阵的逆,有:
当然还有其他方法可以用来计算矩阵的逆,比如高斯消元法。很多线性代数书都断定该方法更适合在计算机上实现,因为它所使用的代数运算较少,这种说法其实是 不正确的。对于大矩阵或某些特殊矩阵来说,这也许是对的。然而,对于低阶矩阵,比如几何应用中常见的那些低阶矩阵,标准伴随矩阵可能更快一些。因为可以为 标准伴随矩阵提供无分支(branchless)实现,这种实现方法在当今的超标量体系结构和专用向量处理器上会更快一些。
矩阵的逆的重要性质:
几何解释
矩阵的逆在几何上非常有用,因为它使得我们可以计算变换的”反向“或”相反“变换 ---- 能”撤销“原变换的变换。所以,如果向量v用矩阵M来进行变换,接着用M的逆M-1进行变换,将会得到原向量。这很容易通过代数方法验证:
正交矩阵的运算法则
若方阵M是正交的,则当且仅当M与它转置矩阵MT的乘积等于单位矩阵,见公式9.8:
矩阵乘以它的逆等于单位矩阵:M M-1 = I
所以,如果一个矩阵是正交的,那么它的转置等于它的逆:
这是一条非常有用的性质,因为在实际应用中经常需要计算矩阵的逆,而3D图形计算中正交矩阵出现又是如此频繁。比如旋转和镜像矩阵是正交的,如果知道矩阵是正交的,就可以完全避免计算逆矩阵了,这也将大大减少计算量。
正交矩阵的几何解释
正交矩阵对我们非常有用,因为很容易计算它的逆矩阵。但怎样知道一个矩阵是否正交,以利用它的性质呢?
很多情况下,我们可以提前知道矩阵是如何建立的,甚至了解矩阵是仅包含旋转、镜像呢,还是二者皆有(记住:旋转和镜像矩阵是正交的)。这种情况非常普遍。
如果无法提前清楚矩阵的某些情况呢?换句话说,对于任意矩阵M,怎样检测它是否正交?为了做到这一点,让我们从正交矩阵的定义开始,以3x3阶矩阵为例。设M是3x3矩阵,根据定义,当且仅当 M MT = I 时M是正交的。它的确切含义如下:
现在做一些解释:
(1)当且仅当一个向量是单位向量时,它与自身的点积结果是1。因此,仅当r1、r2、r3是单位向量时,第1、5、9式才能成立。
(2)当且仅当两个向量是互相垂直时,它们的点积为0。因此,仅当r1、r2、r3互相垂直时其他等式才成立。
所以,若一个矩阵是正交的,它必须满足下列条件:
矩阵的每一行都是单位向量,矩阵的所有行互相垂直。
对矩阵的列也能得到类似的条件,这使得以下结论非常清楚:如果M是正交的,则MT也是正交的。
计算逆矩阵时,仅在预先知道矩阵是正交的情况下才能利用正交性的优点。如果预先不知道,那么检查正交性经常是浪费时间。即使在最好的情况下,先检查正交性 以确定矩阵是否正交再进行转置,和一开始就进行求逆运算也将耗费同样多的时间。而如果矩阵不是正交,那么这种检查完全是浪费时间。
注意,有一个术语上的差别可能会导致轻微的混淆。线性代数中,如果一组向量互相垂直,这组向量就被认为是正交基(orthogonal basis)。它只要求所有向量互相垂直,并不要求所有向量都是单位向量。如果它们都是单位向量,则称它们为标准正交基(orthogonal basis)。这里所讲的正交矩阵的行或列向量都是指标准正交基向量(orthogonal basis vectors),所以由一组正交基向量构造的矩阵并不一定是正交矩阵(除非基向量是标准正交的)。
矩阵正交化
有时可能会遇到略微违反了正交性的矩阵。例如,可能从外部得到了坏数据,或者是浮点运算的累积错误(称作”矩阵爬行“)。这些情况下,需要做矩阵正交化,得到一个正交矩阵,这个矩阵要尽可能地和原矩阵相同(至少希望是这样)。
构造一组正交基向量(矩阵的行)的标准算法是施密特正交化。它的基本思想是,对每一行,从中减去它平行于已处理过的行的部分,最后得到垂直向量。
以3x3矩阵为例,和以前一样,用r1、r2、r3代表3x3阶矩阵M的行。正交向量组r1'、r2'、r3'的计算如公式9.9所示:
现在r1'、r2'、r3'互相垂直了,它们是一组正交基。当然,它们不一定是单位向量。构造正交矩阵需要使用标准正交基,所以必须标准化这些向量。注意,如果一开始就进行标准化,而不是在第2步中做,就能避免所有除法了。
施密特正交化是有偏差的,这取决于基向量列出的顺序。一个明显的例子是,r1总不用改变。该算法的一个改进是不在一次正交化过程中将整个矩阵完全正交化。而是选择一个小的因子k,每次只减去投影的k倍,而不是一次将投影全部减去。改进还体现在,在最初的轴上也减去投影。这种方法避免了因为运算顺序不同带来的误差。算法总结如下:
该算法的每次迭代都会使这些基向量比原来的基向量更为正交化,但可能不是完全正交的,多次重复这个过程,最终将得到一组正交基。要得到完美的结果,就得选择一个适当的因子k并迭代足够多次(如:10次)。接着,进行标准化,最后就会得到一组正交基。
4D向量和4x4矩阵不过是对3D运算的一种方便的记忆而已。
4D齐次空间
4D向量有4个分量,前3个是标准的x,y和z分量,第4个是w,有时称作齐次坐标。
为了理解标准3D坐标是怎样扩展到4D坐标的,让我们先看一下2D中的齐次坐标,它的形式为(x, y, w)。想象在3D中w=1处的标准2D平面,实际的2D点(x, y)用齐次坐标表示为(x, y, 1),对于那些不在w=1平面上的点,则将它们投影到w=1平面上。所以齐次坐标(x, y, w) 映射的实际2D点为(x/w, y/w)。如图9.2所示:
因此,给定一个2D点(x, y),齐次空间中有无数多个点与之对应。所有点的形式都为(kx, ky, k),k≠0。这些点构成一条穿过齐次原点的直线。
当w=0时,除法未定义,因此不存在实际的2D点。然而,可以将2D齐次点(x, y, 0)解释为"位于无穷远的点",它描述了一个方向而不是一个位置。
4D坐标的基本思想相同,实际的3D点被认为是在4D中w=1"平面"上。4D点的形式为(x, y, z, w),将4D点投影到这个"平面"上得到相应的实际3D点(x/w, y/w, z/w)。w=0时4D点表示"无限远点",它描述了一个方向而不是一个位置。
4 X 4 平移矩阵
3x3变换矩阵表示的是线性变换,不包括平移。因为矩阵乘法的性质,零向量总是变换成零向量。因此,任何能用矩阵乘法表达的变换都不包含平移。这很 不幸,因为矩阵乘法和它的逆是一种非常方便的工具,不仅可以用来将复杂的变换组合成简单的单一变换,还可以操纵嵌入式坐标系间的关系。如果能找到一种方法 将3x3变换矩阵进行扩展,使它能处理平移,这将是一件多么美妙的事情啊。4x4矩阵恰好提供了一种数学上的"技巧",使我们能够做到这一点。
暂时假设w总是等于1。那么,标准3D向量[x, y, z]对应的4D向量为[x, y, z, 1]。任意3x3变换矩阵在4D中表示为:
任意一个形如[x, y, z, 1]的向量乘以上面形式的矩阵,其结果和标准的3x3情况相同,只是结果是用w=1的4D向量表示的:
现在,到了最有趣的部分。在4D中,仍然可以用矩阵乘法来表达平移,如公式9.10所示,而在3D中是不可能的:
记住,即使是在4D中,矩阵乘法仍然是线性变换。矩阵乘法不能表达4D中的"平移",4D零向量也将总是被变换成零向量。这个技巧之所以能在3D中 平移点是因为我们实际上是在切变4D空间。与实际3D空间相对应的4D中的"平面"并没有穿过4D中的原点。因此,我们能通过切变4D空间来实现3D中的 平移。
设想没有平移的变换后接一个有平移的变换会发生什么情况呢?设R为旋转矩阵(实际上,R还能包含其他的3D线性变换,但现在假设R只包含旋转),T为形如公式9.10的变换矩阵:
将向量v先旋转再平移,新的向量v'计算如下:
v' = vRT
注意,变换的顺序是非常重要的。因为我们使用的是行向量,变换的顺序必须和矩阵乘法的顺序相吻合(从左到右),先旋转后平移。
和3x3矩阵一样,能将两个矩阵连接成单个矩阵,记作矩阵M,如下:
M = RT
v' = vRT = v(RT) = vM
观察M的内容:
注意到,M的上边3x3部分是旋转部分,最下一行是平移部分。最右一列为[0, 0, 0, 1]T。逆向利用这些信息,能将任意4x4矩阵分解为线性变换部分和平移部分。将平移向量[△x, △y, △z]记作t,则M可简写为:
接下来看w=0所表示的 "无穷远点"。它乘以一个由"标准"3x3变换矩阵扩展成的4x4矩阵(不包含平移),得到:
换句话说,当一个形如[x, y, z, 0]的无穷远点乘以一个包含旋转、缩放等的变换矩阵,将会发生预期的变换。结果仍是一个无穷远点,形式为[x, y, z, 0]。
一个无穷远点经过包含平移的变换可得到:
注意到结果是一样的(和没有平移的情况相比)。换句话说,4D向量中的w分量能够"开关" 4x4 矩阵的平移部分。这个现象是非常有用的,因为有些向量代表“位置”,应当平移,而有些向量代表“方向”,如表面的法向量,不应该平移。从几何意义上说,能将第一类数据当作"点",第二类数据当作"向量".
使用4x4矩阵的一个原因是4x4变换矩阵能包含平移。当我们仅为这个目的使用4x4矩阵时,矩阵的最后一列总是[0, 0, 0, 1]T。既然是这样,为什么不去掉最后一列而改用4x3矩阵呢?根据线性代数法则,由于多种原因,4x3矩阵不符合我们的需求,如下:
(1)不能用一个4x3矩阵乘以另一个4x3矩阵。
(2)4x3矩阵没有逆矩阵,因为它不是一个方阵。
(3)一个4D向量乘以4x3矩阵时,结果是一个3D向量。
为了严格遵守线性代数法则,我们加上了第4列。当然在代码中,可以不受代数法则的约束。
一般仿射变换
3x3矩阵仅能表达3D中的线性变换,不能包含平移。经过4x4矩阵的武装后,现在我们可以构造包含平移在内的一般仿射变换矩阵了。例如:
(1)绕不通过原点的轴旋转。
(2)沿不穿过原点的平面缩放。
(3)沿不穿过原点的平面镜像。
(4)向不穿过原点的平面正交投影。
它们的基本思想是将变换的"中心点"平移到原点,接着进行线性变换,然后再将"中心点"平移回原来的位置。开始使用平移矩阵T将点P移到原点,接着用线性变换矩阵R进行线性变换,最终的仿射变换矩阵M等于矩阵的积,即:TRT-1。T-1是平移矩阵,执行和T相反的变换。
观察这种矩阵的一般形式,它非常有趣。让我们先用 "分块"形式写出前面用到的T、R、T-1。
可以看出,仿射变换中增加的平移部分仅仅改变了4x4矩阵的最后一行,并没有影响到上面所包含的线性变换的3x3部分。
透视投影
学习透视投影最好的方法是将它和平行投影相比较。正交投影也称作平行投影,因为投影线都是平行的(投影线是指从原空间中的点到投影点的连线)。正交投影中的平行线如图9.3所示:
3D中的透视投影仍然是投影到2D平面上,但是投影线不再平行,实际上,它们相交于一点,该点称作投影中心。如图9.4所示:
因为投影中心在投影平面前面,投影线到达平面之前已经相交,所以投影平面上的图像是翻转的。当物体远离投影中心时,正交投影仍保持不变,但透视投影变小了。如图9.5所示:
图9.5中,右边的茶壶离投影平面更远,所以它的投影比离投影平面较近的那个茶壶小。这是一种非常重要的视觉现象,称作透视缩略。
小孔成像
透视投影在图形学中非常重要,因为它是人类视觉系统的模型。实际上,人类视觉系统远比这复杂,因为我们有两只眼睛,而且对于每只眼睛,投影表面(视网膜) 不是一个平面。所以,让我们来看一个简单些的例子----小孔成像。小孔成像系统就是一个盒子,一侧上有小孔,光线穿过小孔照射到另一侧的背面,那里就是 投影平面。如图9.6所示:
图9.6中,盒子左面和右面是透明的,以使你能看见盒子内部。注意盒子内部的投影是倒着的,这是因为光线(投影线)已经在小孔处(投影中心)相交了。
让我们探索小孔成像背后的几何原理。设想一个3D坐标系,它的原点在投影中心,z轴垂直于投影平面,x和y轴平行于投影平面。如图9.7所示:
让我们看看能否计算出任意点p通过小孔投影到投影平面上的坐标p'。首先,需要知道小孔到投影平面的距离,设为d。因此,投影平面为z=-d。现在,从另一个角度来看问题,求出新的y。如图9.8所示。
由相似三角形得到:
注意小孔成像颠倒了图像,py和py'的符号相反。px'的值可通过类似的方法求得:
所有投影点的z值都是相同的:-d。因此,点p通过原点向平面z=-d投影的结果如公式9.11所示:
在实际应用中,负号会带来不必要的复杂性。所以将投影平面移到投影的前面(也就是说,平面z=d),如图 9.9所示:
当然,这对于实际的小孔成像是不可能的。因为设置小孔的目的就是使光线只能通过小孔,但在计算机数学世界中,可以不理会这些规定。如你所愿,将投影平面移到投影中心前面,烦人的负号消失了,如公式9.12所示:
使用4x4矩阵进行透视投影
从4D到3D的变换就意味着除法运算,因此我们可以利用4x4阶矩阵来编写代码,以实现透视投影。基本思想是提出一个关于p'的公式,其中的x、y、z有公分母,然后构造一个4x4矩阵,使w与这个公分母相等。这里我们假设初始点处有w=1。
先对3D形式表达的p'公式变形,可以得到:
将4D齐次向量变换到3D时,要用4D向量除以w,反推可知p'的4D形式为:
[x y z z/d]
因此我们需要一个4x4矩阵,它可接收一个奇异的齐次向量。该向量的形式为[x, y, z, 1],然后将其变换为上述形式。这样的矩阵如公式9.13所示:
这样就得到了一个4x4投影矩阵,有几个需要注意的地方:
(1)乘以这个矩阵并没有进行实际的透视投影变换,它只是计算出合适的分母。投影实际发生在从4D向3D变换时。
(2)存在多种变换。例如,将投影平面放在z=0处而投影中心在[0, 0, -d],这将导致一个不同的公式。
(3)这里看起来比较复杂,似乎只需要简单地除以z,不必劳烦矩阵。那么为什么要使用齐次矩阵呢?第一,4x4矩阵提供了一个方法将投影表达为变 换,这样就能和其他变换相连接;第二,使得投影到不平行于坐标轴的平面变得可行。实际上,我们不需要齐次坐标做任何运算,但4x4矩阵提供了一种简洁的方 法表达和操纵投影变换。
(4)实际的图形几何管道中的投影矩阵不像这里导出的那样,还有许多重要的细节需要考虑。如用以上矩阵对向量进行变换后,z值实际上被舍弃了,而很多图形系统的z缓冲用到了该值。