(连载)边喝咖啡边学Unity――第二章 预备知识体系(2)(二)

2015-01-27 06:04:39 · 作者: · 浏览: 30
基的过程。其过程必定不包含平移。

那么我们怎么才能表达平移?

我们前面讲了坐标与矩阵的乘法等于变换本身,因此我们假定2个坐标(1,1)(2,2)构成的线段,将其书写为2个行向量[1 1][2 2],将其左乘一个2x2单位矩阵(我们认为2x2单位矩阵是一个x,y方向上缩放系数都为1的缩放矩阵)完成线性变换:


[1 1] \变换后的结果仍然为[1 1],[2 2]同理。得到的线段(图形)没有发生任何变画

我们对这个变换矩阵进行任意修改:将[1 1]对角线上的值进行修改,发现变换过程产生了等比缩放。将没有在这条对角线上的值进行修改,发现变换过程产生了旋转。

除此之外这个2x2矩阵上面已经没有其他地方可以让我们修改能够产生平移变换的可能性了。于是我们不得不提出一个大胆的设想:我们能否得到一个包含有更多数的矩阵来完成变换,使该矩阵能有地方让我们修改其值使原图发生非线性变换?

答案是肯定的,在认知的过程中思维的变迁与升华是必不可少了。于是天才一般的想法被提出来:我们以3维矩阵、向量来表达2维空间中的变换和点。

我们来看对于点[1 1]扩展一个维度之后[1 1 1],我们对扩展过后的这个点坐标给予以下要求:

这不是一个3维空间中的点,它仍然是2维空间中[1 1]这个点。第三个维度我们称之为w。我们想象不出来这个[1 1 1]的点其意义为何的时候,我们只能看到这个点在2维空间中的影子(投影),我们由这个影子反过来来想象它。对于点[1 1 1],[2 2 2],[3 3 3],他们投影在二维空间中都是[1 1]这个点,投影的过程即将前面2维分别除以第三个维度w。当w=0时,除法无意义,因此我们认为点[x,y,0]在二维空间中的意义为无穷远的点

这个空间我们称这个2维空间的3维齐次空间。这个[x,y,w]形式的坐标,我们称其为改2维坐标的3维齐次坐标。同样的,我们的2维单位矩阵 \,当w=1时,对应着一个3维齐次单位矩阵 \


我们再次以齐次行向量与齐次单位矩阵的左乘表达变换:

[x y w] \,此时左矩阵列数与右矩阵行数仍然相等,乘法仍然有意义。

我们再观察,齐次矩阵中是否有地方可以让我们的坐标系产生平移的可能?


\



齐次矩阵中原2维矩阵的数据项我们不必尝试了,我们试着修改多出来的abcd。

[x y w]\=[x+a,y+b,w ] (结果矩阵中:\)

不可思议的事情发生了,由于我们对于齐次空间的定义,任意点[x,y,w],x/w , y/w相等的两个点我们认为是同一个点。于是我们可以看到这个变换矩阵令原坐标系中的任意点[x y]变换后都成为了[x+a y+b]!也就是任何图形、线段都沿x方向平移了a,沿y方向平移了b。

结论:对于n维空间中的图形(坐标系),nxn矩阵可以表达线性变换,引入n+1维齐次空间,即可用n+1维齐次矩阵乘法来表达平移变换。而原线性变换,依然可以在该齐次矩阵中的原对应位置表达线性变换。

于是齐次矩阵将线性变换与平移变换统一到了一起。我们将线性变换与平移变换都发生的变换叫做仿射变换

换句话讲,一个nxn矩阵,可以表达任意的n-1维空间中的仿射变换。

由此我们得到三维空间中的平移矩阵,显然是一个3+1=4维的矩阵:


\

我们再回到几何层面上,我们认为对位置有意义的量,进行平移才有意义,本身没有位置概念的量,我们进行平移没有意义。最典型的就是点和向量。虽然我们前面说向量可以由终点来表达,但是狭义上的点是有位置的,而向量只有大小和方向。因此我们不能对一个狭义上的向量进行平移变换。

透视投影变换与投影矩阵

我们简单的提一下投影变换。投影变换通常发生在将一个3维空间中的物体投影至一个平面上(阳光将人照射出来的影子投影在墙上)。而我们表达一个3维平面最简单的3个平面分别是x=d,y=d,z=d。他们各自是与圆点距离d处的平面。

我们假设要将一个三维图形投影至z=d这个平面,那么任意的齐次点[x y z]投影至z=d平面上,得到的点坐标应为:[x y z ]/(z/d)=[x y d]将z消除得到了2维的空间(图形). 因此我们构造一个w为1的齐次空间,另[x y z 1]投影之后变为[x y z z/d],那么矩阵构造出来为:


\



任意点[x y z 1]与该矩阵相乘得到[x y z z/d],[x y z z/d]回到原空间则为[x y d],该矩阵就是三维空间中向z=d平面投影的投影矩阵。

方位与角位移

在掌握了向量、矩阵的一些基本知识之后,我们问自己一个问题:

一个向量有没有角位移?一个物体有没有角位移?

我们知道向量只有大小和方向,即使你要强迫一个向量绕自己旋转,旋转后向量仍然大小和方向没有改变,我们认为向量还是那个向量。但是如果说我们让一个物体绕自己旋转,比如把一个人翻过来,我们还认为是一样吗?由于地球引力的关系,被倒过来的人能够明显感觉到自己的状态发生了改变。而这种改变不单单是我们把一个人从某个地方弄到另外一个地方这种位移。在物理上我们称这个人发生了角位移。

我们将旋转的程度称为角位移。位移往往用来表达物体的位置,角位移往往用来表达物体的方位

我们知道了n维空间中的位移可以用n个数字来表示。例如2维空间中的点朝x移动了5,朝y移动了10,那么用5,10 两个数字即可表达这个位移。

那么3维空间中的角位移又如何来表达呢?

矩阵表达角位移

我们可以构造一个3维的旋转变换矩阵来表达3维空间中的角位移(这种矩阵我们前面已经给出)。这种表达方式非常地直接,但是并不简洁。我们了解下矩阵表达角位移的优缺点

优点:立即性;更适合底层图形API直接使用;多个角位移连接时只需要连续相乘即可得到最后的角位移;只需要简单的将这个矩阵转置即可求得这个角位移的逆;

缺点:占用更多的空间(3维空间需要9个数来表达角位移);晦涩难懂(我想读者应该已经有所体会);有冗余数据、有可能发生矩阵蠕变。

欧拉角(Euler Angle)表达角位移

神马?我们单纯的描述一个物体旋转的情况,竟然要搬出一个3x3矩阵?我们不能忍!于是乎本章开头提到的欧拉角登场了。欧拉角由著名的数学家欧拉(Euler)提出,并且以他的名字命名。我们看看欧拉角是个什么角,欧拉角有什么厉害之处:

欧拉角将一个三维物体的旋转分解为分别绕3个两两垂直的轴线的旋转。至于哪3个轴,按照什么顺序分解,欧拉没有告诉我们,但是最有意义的情况是我们按3维坐标系的3个轴按照一定的顺序将旋转分解。这个顺序有很多种约定,我们这里提一下”heading-pitch-bank”约定。

即在左手坐标系中,我们继续伸出左手,3个手指两两垂直,得到我们前面提到的左手坐标系,食指指向即y+方向的旋转量我们称为heading,中指指向的z+方向的旋转量我们称为bank,大拇指指向的z+方向的旋转量我们成为pitch。

由此我们将一个物体任意的旋转分解为3个旋转量,分别得到3个角度。我们可以由3个数组成的序列来描述近乎所有的旋转!但是欧拉角仍然无法表达所有的旋转。最著名的就是万向节死锁现象。即当pitch=+-90°时heading与bank都竖直从而减少了一个旋转度,此问题至今没有什么好的办法解决。

优点:容易使用;占用的数最少;简洁;所有的欧拉角表达出来的角位移都是合法的。

缺点:不唯一性(360°和0°虽然数值变化了但是表达的方位没变);最难插值(很难在两个欧拉