OpenGL學(xué)習(xí)腳印: 理解坐標(biāo)系及坐標(biāo)變換(上)
寫在前面
本文為學(xué)習(xí)計算機圖形學(xué)及利用OpenGL開發(fā)圖形程序做數(shù)學(xué)準(zhǔn)備工作。有關(guān)3D math的學(xué)習(xí)不是一蹴而就的,因此這里整理總結(jié)的是圖形學(xué)中的基本數(shù)學(xué)問題。參考資料列在文章末尾。如有錯誤請糾正我。
鑒于OpenGL中使用列向量表達向量,因此本節(jié)統(tǒng)一使用列向量表達向量,必要時使用轉(zhuǎn)置表達行向量。
1.三大空間
在計算機圖形學(xué)中,需要表示和處理像點和線段這樣的幾何元素,為此要用到的數(shù)學(xué)知識可以在各種類型的抽象空間的研究中找到。
這里我們認(rèn)識3類這樣的空間:向量空間vector space(線性空間linear space)、仿射空間affine space、歐幾里得空間Euclid space 。
1.1 向量空間
向量空間包含兩類對象: 標(biāo)量(scalar)和向量(vector)。
標(biāo)量是只有大小而沒有方向的量。例如實數(shù)就是標(biāo)量的例子。標(biāo)量是對我們平時所用數(shù)字的技術(shù)稱謂。使用該術(shù)語時是想強調(diào)數(shù)量值。
在兩個標(biāo)量之間定義了兩種基本運算,即加法和乘法,這兩種運算滿足交換律、結(jié)合律和分配律。這就是我們熟悉的加減法中使用的規(guī)律:
- 加法交換律:a+b=b+a
-
- 乘法交換律:a*b=b*a
-
- 加法結(jié)合律:(a+b)+c=a+(b+c)
- 乘法結(jié)合律:a*b*c=a*(b*c)=(a*b)*c
-
- 分配律:(a+b)*c=a*c+b*c
同時通過加法和乘法的逆元(加法逆元就是相反數(shù),乘法逆元就是倒數(shù)),隱含地定義了減法和除法。
為了能夠處理方向,我們需要另一種類型,即向量。物理學(xué)家和數(shù)學(xué)家使用向量這個術(shù)語來表示任何既有方向又有大小的量。
關(guān)于向量,定義了兩種運算:向量-向量加法和標(biāo)量-向量乘法。
向量-向量加法是封閉的,即任意u,v∈V,則 u+v ∈V。向量加法滿足交換律和結(jié)合律。
標(biāo)量-向量乘法是這樣定義的,對于任意的標(biāo)量a和任意的向量u,則au是V中的一個向量。
標(biāo)量-向量乘法滿足分配律:
a(u+v)=au+av
(α+β)u = au+βu
關(guān)于向量的介紹先到這里,后面在必要時會再展開。
如果想獲取向量與坐標(biāo)全面的在線教案,可參考:六盤水師范學(xué)院《解析幾何》教案。
1.2 仿射空間
仿射空間是向量空間的拓展,除了標(biāo)量和向量,還包括另外一種對象:點。
在向量空間中,沒有像位置和距離這樣的幾何概念。如果把由有向線段構(gòu)成的向量空間作為考慮幾何問題的自然向量空間,就會遇到困難,因為這些向量就像物理中的向量那樣,具有大小和方向,但是沒有位置。我們可以通過引入坐標(biāo)系來考慮問題。坐標(biāo)系如下圖所示:

但是在向量空間中沒有辦法表示原點O,因為向量空間中只有標(biāo)量和向量。因此就引入了仿射空間。
仿射空間比向量空間多一類實體:點。
設(shè)P,Q,R為仿射空間中的點。在仿射空間中定義了新的運算:點-點減法,這個運算的結(jié)果就是一個向量。
對于任意兩點P,Q,v = P-Q,其中v為V中的一個向量;反之對于任意v和P,我們總可以找到一個Q使該關(guān)系成立,這樣就定義了一種點-向量加法:P = Q+v。點-向量加法可以看做把點Q移動到新位置P,移動的長度和方向由向量v決定。如下圖所示:

1.3 歐幾里得空間
雖然仿射空間里包含了幾何模型的必要元素,但是在仿射空間中不能度量兩個點相距多遠,或者說沒有向量長度的概念。
歐幾里得空間是向量空間的拓展,它增加了對大小或者距離的度量,可以定義線段的長度等概念。嚴(yán)格地說,歐幾里得空間只包含向量和標(biāo)量。
我們定義一種的新的運算,內(nèi)積(inner product)或者叫點積(dot product),該運算由兩個向量得到一個實數(shù)。
內(nèi)積滿足這樣的性質(zhì): 對于任意3個向量u,v,w和變量α,β都有:
u.v=v.u(交換律)
(αu+βv).w = αu.w+βv.w
對于v ≠0,則有v.v > 0;如果u.v = 0,則稱u和v是正交的(orthogonal)
一個向量的大小(長度,也稱為向量的模)通常定義為:

把仿射空間中點的概念加入到歐幾里得空間后,則兩點之間的距離,可以看做向量的模,例如兩點P和Q,則

2.坐標(biāo)系基本概念
2.1 坐標(biāo)系定義
使用坐標(biāo)系是為了以代數(shù)的方法來研究幾何,這就是解析幾何的方式。通過建立一個坐標(biāo)系使得空間中點用有序?qū)崝?shù)組表示,空間圖形用方程表示,這樣就方便研究幾何圖形的性質(zhì)。
定義一個坐標(biāo)系需要指定:
- 坐標(biāo)系的維度 2D, 3D, 4D等等
- 定義坐標(biāo)空間軸的向量,這些向量成為基向量,他們有名字,例如x,y,z;這些向量不一定非得互相正交(只要線性無關(guān)即可),但是每一個維度必須只有一個軸。
- 坐標(biāo)系的原點O,原點是導(dǎo)出其他點的參考點。
- 一個表明空間中點是否合法的區(qū)域,在此區(qū)域之外的點就不再合法。這個區(qū)域根據(jù)空間不同,可以是無窮的。
這里,維度已由基向量維數(shù)確定,合法區(qū)域我們一般是無窮的,但是在圖形處理中某些坐標(biāo)空間是有限的,例如規(guī)范化設(shè)備空間。
基向量不一定非得正交,可以參見:《Learning Modern 3D Graphics Programming》中Spaces介紹。
2D笛卡爾坐標(biāo)系如下圖所示:

在2D笛卡爾坐標(biāo)系中(x,y)可以定位一個點。坐標(biāo)的每個分量都是到相應(yīng)軸的有符號距離。例如,x分量表示改變到y(tǒng)軸的有符號距離,同樣,y分量表示該點到x軸的有符號距離。這里,有符號距離,是指在某個方向上為正,而在相反的方向上為負(fù),需要根據(jù)相應(yīng)軸的正方向來定。
給2D笛卡爾坐標(biāo)系增加第三個維度,即增加一個Z軸,則定義了3D坐標(biāo)系,如下圖所示:

3D中,任意一對軸都定義了一個平面并垂直于第3個軸,例如x,y軸的xy平面垂直于z軸;同樣xz平面垂直于y軸,yz平面垂直于x軸。
我們可以認(rèn)為這三個平面是3個2D笛卡爾空間。
3D笛卡爾空間中,定位一個點需要(x,y,z)3個數(shù)。3個分量分別代表該點到y(tǒng)z、xz、xy平面的有符號距離。如下圖所示:

2.2 左手/右手坐標(biāo)系及左/右手規(guī)則
對于任意2個2D坐標(biāo)系,我們通過旋轉(zhuǎn)、移動翻轉(zhuǎn)可以將兩個坐標(biāo)系xy軸的指向相同。
但是對于3D坐標(biāo)系,任意兩個坐標(biāo)系卻不能等價。實際上,存在兩種完全不同的3D坐標(biāo)系:左手坐標(biāo)系和右手坐標(biāo)系。如果同屬于左手坐標(biāo)系或者右手坐標(biāo)系,則可以通過旋轉(zhuǎn)來重合,否則不可以。
關(guān)于左右手坐標(biāo)系理解可參考下圖:

如上右圖右手坐標(biāo)系,這里拇指、食指、其余手指分別代表x,y,z軸的正方向。
高等數(shù)學(xué)教材上上使用的是右手坐標(biāo)系,DirectX使用左手坐標(biāo)系,OpenGL使用的是右手坐標(biāo)系。
同樣還存在一個左手規(guī)則和右手規(guī)則,主要用于判斷當(dāng)物體繞軸旋轉(zhuǎn)時正方向的判定問題。
對于左手規(guī)則,確定一個旋轉(zhuǎn)軸后,左手握成拳頭,拇指指向旋轉(zhuǎn)軸的正方向,則其余手指彎曲方向即為旋轉(zhuǎn)的正方向。從旋轉(zhuǎn)軸正向末端來看,正向旋轉(zhuǎn)是順時針的。對于右手規(guī)則,有同樣的方法??蓞⒁娤聢D:

關(guān)于如何快速判定旋轉(zhuǎn)正向,還有一個巧妙的方法,可以參見:判斷三維坐標(biāo)系旋轉(zhuǎn)正方向的簡單方法。
3.坐標(biāo)變換
在計算機圖形學(xué)中,為了更方便的描述物體,對物體進行處理,需要使用多個坐標(biāo)系。
使用多個坐標(biāo)系的原因就是:某些信息只能在特定的上下文環(huán)境中才能獲取(參考自[2])。
怎么理解這句話呢?補充一個例子吧。比如,定義一個機器人模型,機器人模型的原點設(shè)在身體中央,成為一個坐標(biāo)系C;同時為機器人構(gòu)造復(fù)雜的頭部模型時,需要使用一個新坐標(biāo)系C1;構(gòu)造機器人手部時需要一個新的坐標(biāo)系C2;那么要想獲取手指離鼻子的距離distance,則必須在C坐標(biāo)系中獲取,而在C1或者C2兩個局部坐標(biāo)系中卻無法獲取。那么需要將C1和C2中手指和機器人鼻子的局部坐標(biāo)轉(zhuǎn)換為C坐標(biāo)系中位置,才能計算其距離distance。
這里引出一個重要問題: 怎么在一個坐標(biāo)系中描述另一個坐標(biāo)系?
所謂坐標(biāo)變換,就是知道某一點的坐標(biāo),怎么樣在另一個坐標(biāo)系中描述該點。這就需要坐標(biāo)變換。
個人理解,坐標(biāo)轉(zhuǎn)換,也就是從另一個坐標(biāo)系來"看"原坐標(biāo)系中的點,這個點還在原來坐標(biāo)系,只是用另外一組原點和基向量來解釋而已,因此坐標(biāo)值發(fā)生了變換。坐標(biāo)變換并不神秘。
3.1 二維變換引例
這里以csdn 湯永康 博客
坐標(biāo)旋轉(zhuǎn)變換公式的推導(dǎo)坐標(biāo)系的旋轉(zhuǎn)為例,該坐標(biāo)系變換如下圖所示:

這里將原坐標(biāo)系XOY下點P(x,y),經(jīng)過旋轉(zhuǎn)theta后,變換到新坐標(biāo)系SOT下點(s,t)。
那么,點P經(jīng)過旋轉(zhuǎn)變換后,變換到坐標(biāo)系SOT下的坐標(biāo)與原坐標(biāo)系下坐標(biāo)之間的關(guān)系經(jīng)推導(dǎo)后如下所示:

推導(dǎo)過程可參見原文,原文利用點在坐標(biāo)系中的位置關(guān)系進行推導(dǎo)的。
本節(jié)稍后將使用坐標(biāo)系變換的觀點,直接推導(dǎo)出變換矩陣。
3.2 坐標(biāo)系變換
3.2.1 復(fù)習(xí)預(yù)備概念
向量空間:
設(shè)V為n維向量的集合,如果集合V非空,且集合V對于向量的加法和乘數(shù)運算封閉,那么就稱集合V為向量空間。
這里封閉的意思是指在集合V中可以進行向量的加法和乘數(shù)運算。具體的講即是滿足:
若a∈V,b∈V則a+b∈V
若a∈V,λ∈R,則λa∈V
例如3維向量的全體構(gòu)成3維空間。
一般地,由向量組u生成的向量空間記為:

線性無關(guān):
n個向量的線性組合(linear combination)是形如下式的一個向量:

如果使得:u=0成立的唯一一組標(biāo)量是:

則稱這組向量是線性無關(guān)的(linear independent)。
基向量組:
設(shè)V為向量空間,如果r個向量都屬于V,且滿足:
1)r個向量線性無關(guān)
2)V中任意一個向量都可以由這r個向量線性表示
那么,這r個向量稱為向量空間V的一個基,r稱為向量空間的維數(shù),并稱V為r維向量空間。
實際上,在一個向量空間里,線性無關(guān)向量組中向量數(shù)目的最大值就是這個空間的維數(shù),如果一個向量空間的維數(shù)是n,那么任何n個線性無關(guān)的向量都構(gòu)成了一個基。
坐標(biāo):
如果在向量空間中選取一個向量組u作為基,那么任意一個向量x可以唯一地表示為:

則稱數(shù)組λ為向量x在基u下的坐標(biāo)。
3.2.2 坐標(biāo)變換
假設(shè)n維向量空間,有兩個基向量組如下:
,
則對于一個給定的向量w可以表示為:


我們可以把w的坐標(biāo)寫成:

也可以寫成

這取決于使用哪個基。
現(xiàn)在來考慮如何從w變到w‘。
基u中每個向量都可以用基v來表示,因此存在一組標(biāo)量λ使得:

利用列矩陣重新表達向量w,則有:

由上兩式子可得:

矩陣A是這兩個基之間變換的矩陣表示,也稱為過渡矩陣。利用過渡矩陣可以再兩個基下表示之間進行切換,即進行坐標(biāo)轉(zhuǎn)換。
下面舉出一個例子,幫助熟悉。
這里使用列向量來表達單個向量。
假設(shè)向量w在基v下表示為:

則有:

設(shè)另一基u滿足:

則兩個基之間的過渡矩陣為:

則有:

則可以求得:



3.2.3 求出變換矩陣的技巧
從上述可以看出,要進行坐標(biāo)變換,關(guān)鍵是怎么樣快速構(gòu)建變換矩陣。
這里摘自【2】中的結(jié)論,導(dǎo)出如下:
對于基向量[1,0,0]^T、[0,1,0]^T、[0,0,1]^T(以列向量表示),任意矩陣M乘以它們時的情況:



觀察發(fā)現(xiàn)矩陣M乘以[1 0 0]^T時得出的是M的第一列,其他兩列有同樣的結(jié)果。
這里得出一個重要的結(jié)論:矩陣M的每一列都能解釋為轉(zhuǎn)換后的基向量。
(參考書[2]中使用行向量推導(dǎo),則結(jié)論為矩陣每一行為轉(zhuǎn)換后的基向量)。
這個結(jié)論能幫助我們反向建立矩陣的可能。給出一個期望的變換(如旋轉(zhuǎn)、縮放等),能夠構(gòu)造一個矩陣代表此變換。
我們要做的一切就是計算基向量的變換,然后將變換后的基向量填入矩陣。
設(shè)基向量組u,v滿足如下關(guān)系,則兩個基下坐標(biāo)b,a滿足關(guān)系如下:

由于使用列向量表達向量,因此,使用上述填充矩陣方法實際上找到的就是這個公式里的M矩陣的轉(zhuǎn)置 ,注意這個細節(jié)。
3.2.4 二維變換的示例
首先利用這個方法,我們推導(dǎo)上述二維旋轉(zhuǎn)的坐標(biāo)如下:

這里,基向量轉(zhuǎn)換的基向量組成的矩陣為(每列構(gòu)成的):

則原來的XOY坐標(biāo)系下點p(x,y)在新坐標(biāo)系SOT中坐標(biāo)為:

3.2.5 齊次坐標(biāo)系下變換
上面的討論中的變換,可以實現(xiàn)對一個基的旋轉(zhuǎn)和縮放得到另一個基的變換。但是上面的變換中,原點是不變的。這樣不能表示平移變換。而借助齊次坐標(biāo)系我們可以實現(xiàn)標(biāo)架變換,同時仍然使用矩陣來表示標(biāo)架變換。
標(biāo)架(frame)是圖形學(xué)教材[1]引入的一個術(shù)語,原點和基向量決定一個標(biāo)架。
標(biāo)架的一個不太嚴(yán)謹(jǐn)?shù)恼f法是:它把向量坐標(biāo)系的原點固定在了某個點P0處。
在一個給定的標(biāo)架下,每個向量w和點P唯一的表示為:

這樣表示一個向量需要3個標(biāo)量,而表示一個點需要3個標(biāo)量和原點的位置。
通過使用標(biāo)架,我們可以避免向量和點的混淆。
齊次坐標(biāo)系:
齊次坐標(biāo)(homogeneous coordinate)可以克服點和向量在表示形式上一樣(3維空間中都是x,y,z,3個分量表達)而導(dǎo)致混淆的缺點。
齊次坐標(biāo)使用四個分量來表達3維空間中的點和向量。
在由(P0,v1,v2,v3)確定的標(biāo)架中,任一點P可以唯一地表示為:

通過定義點和標(biāo)量0,1的乘法:
0.P = 0
1.P = P
我們可以利用矩陣乘法把點P形式地表示為:

這里嚴(yán)格來講并不是點積,但是把它當(dāng)做點積來計算。
在同一標(biāo)架下,任意一個向量w可以寫為:

至此明確了,在齊次坐標(biāo)系下,向量第四個分量,稱為w分量,為0;而點的w分量為1。
設(shè)有兩個標(biāo)架(v,P0)和(u,Q0),把第二個標(biāo)架的基向量和參考點用第一個標(biāo)架來表示:

把方程寫為矩陣形式:

其中M是一個4x4矩陣:

假設(shè)a和b是同一點或者向量在這兩個標(biāo)架下的齊次坐標(biāo)表示,則有:

因此可得:

根據(jù)該式可以實現(xiàn)兩個標(biāo)架下坐標(biāo)之間的轉(zhuǎn)換。
這里M的轉(zhuǎn)置矩陣為:

注意: 上面我們討論的通過基向量變換情況,來構(gòu)造M轉(zhuǎn)置的方式,在其次坐標(biāo)系下需要把原點也包括進去,原點的變換寫在第4列。
3.2.6 齊次坐標(biāo)系下變換示例
這里摘自教材[1]的一個例子很有代表性。
如下圖所示,世界標(biāo)架下指定相機位置:

將照相機指定在世界標(biāo)架的點P(1,0,1,1)位置處,指向世界標(biāo)架的原點。則照相機的這個指向可以用向量n=(-1,0,-1,0)來表示。
同時照相機的觀察正向和世界標(biāo)架的y軸正方向一致為v=(0,1,0,0),這樣利用叉積找出第三個方向u=nxv = (1,0,-1,0)。這樣照相機構(gòu)成的標(biāo)架則為(u,v,n,P)。
這里可以構(gòu)造出把點和向量從世界標(biāo)架下轉(zhuǎn)換到照相機標(biāo)架下表示的矩陣:

這里M矩陣的轉(zhuǎn)置中,每一列即為世界標(biāo)架的基向量和原點,轉(zhuǎn)換后的對應(yīng)向量和點。
我的感覺,我們一開始構(gòu)造的就是M的轉(zhuǎn)置,所以從M的轉(zhuǎn)置,而不是M矩陣思考會輕松很多。
這里取世界標(biāo)架的原點,這個點在照相機標(biāo)架下的坐標(biāo)為:

也就是說,世界標(biāo)架下原點(0,0,0,1),在照相機標(biāo)架下解釋為(0,0,1,1)點,即在照相機標(biāo)架的n軸上。
而照相機標(biāo)架的原點(0,0,0,1),在世界標(biāo)架下解釋為點P(1,0,1,1)。
上篇,到此結(jié)束,下篇還要繼續(xù)整理包括仿射變換、投影變換以及結(jié)合OpenGL具體變換的展開。
4.主要參考資料
[1] 交互式計算機圖形學(xué)-基于OpenGL著色器的自頂向下方法 第六版 電子工業(yè)出版社
[2] 3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā) 清華大學(xué)出版社
[3] 線性代數(shù) 同濟大學(xué)第五版
|