Note
這是對(duì)MIT Foundation of 3D Computer Graphics第5章的翻譯,本章講解了圖形中坐標(biāo)系的應(yīng)用迁沫,涵蓋了使用變換矩陣操縱物體和變化視角的基本技術(shù)芦瘾。本書內(nèi)容仍在不斷的學(xué)習(xí)中,因此本文內(nèi)容會(huì)不斷的改進(jìn)集畅。若有任何建議近弟,請(qǐng)不吝賜教ninetymiles@icloud.com。
注:文章中相關(guān)內(nèi)容歸原作者所有挺智,翻譯內(nèi)容僅供學(xué)習(xí)參考祷愉。
另:Github項(xiàng)目CGLearning中擁有相關(guān)翻譯的完整資料、內(nèi)容整理、課程項(xiàng)目實(shí)現(xiàn)谣辞。
已經(jīng)完成的章節(jié)
- 第一章
- 第二章
- 第三章
- 第四章
- 第五章
- 第六章
- 第七章
- 第八章
- 第九章
- 第十章
- 第十一章
- 第十二章
- 第十三章
- 第十四章
- 第十五章
- 第十六章
- 第十七章
- 第十八章
- 第十九章
- 第二十章
- 第二十一章
- 第二十二章
- 第二十三章
- 附錄B-仿射函數(shù)基礎(chǔ)
圖形中幀(坐標(biāo)系)的應(yīng)用(Frames in Graphics)
目前為止迫摔,已經(jīng)講解了點(diǎn)和矩陣變換的基礎(chǔ),我們將詳解它們?cè)谟?jì)算機(jī)圖形中通常如何被使用泥从。隨后我們會(huì)討論多種建模運(yùn)用(modeling manipulation)和成像操作(imaging operation)。
5.1 世界沪摄、物體和眼睛幀(World, Object and Eye Frames)
當(dāng)描述一個(gè)場(chǎng)景的幾何形狀時(shí)躯嫉,我們會(huì)開始于一個(gè)被稱為世界幀(world frame)的右手性的正交標(biāo)準(zhǔn)幀(right handed orthonormal frame), 。世界幀(world frame)絕對(duì)不會(huì)被我們改動(dòng)杨拐。然后其它幀能被關(guān)聯(lián)于這個(gè)世界幀(world frame)所描述祈餐。如果我們借助關(guān)聯(lián)于世界幀(world frame)的坐標(biāo)表達(dá)某個(gè)點(diǎn)的地址,那么這些坐標(biāo)將被稱作世界坐標(biāo)(world coordinates)哄陶。
假設(shè)我們希望建模一個(gè)正在場(chǎng)景中運(yùn)動(dòng)的汽車帆阳。我們會(huì)想借助“特別”的頂點(diǎn)坐標(biāo)來建模物體的幾何形狀,這樣的頂點(diǎn)不需要我們時(shí)刻意識(shí)到場(chǎng)景中物體坐標(biāo)的全局替換屋吨。同樣地蜒谤,我們會(huì)想在場(chǎng)景中來回移動(dòng)汽車而不用改變這些坐標(biāo)。這種行為可以借助物體幀(object frame)完成至扰。
針對(duì)場(chǎng)景中的每個(gè)物體鳍徽,我們?yōu)槠潢P(guān)聯(lián)一個(gè)右手性的正交標(biāo)準(zhǔn)物體幀(right handed orthonormal object frame) 。現(xiàn)在我們可以借助關(guān)聯(lián)于物體坐標(biāo)系(object‘s coordinate system)的坐標(biāo)表示物體各個(gè)部分的地址敢课。這些坐標(biāo)被稱為物體坐標(biāo)(object coordinates)并且會(huì)被存儲(chǔ)在計(jì)算機(jī)程序中阶祭。要移動(dòng)整個(gè)物體,我們只要更新
即可直秆,不需要更改物體上對(duì)應(yīng)點(diǎn)的任何物體坐標(biāo)(object coordinates)濒募。
物體坐標(biāo)系(object‘s coordinate system)和世界幀(world frame)之間的關(guān)系通過并行的(affine)矩陣O表達(dá)。也即是
在我們的計(jì)算機(jī)程序中圾结,我們會(huì)存儲(chǔ)矩陣O瑰剃,借助上面的公式,這個(gè)矩陣可被理解為將世界幀(world frame)關(guān)聯(lián)到object‘s coordinate system(物體坐標(biāo)系)疫稿。要移動(dòng)幀培他,我們改變矩陣O。
在真實(shí)世界中遗座,當(dāng)我們想要生成一張3D環(huán)境的2D圖像舀凛,我們會(huì)在場(chǎng)景中某處放置一臺(tái)相機(jī)。圖片中每個(gè)對(duì)象的位置基于到相機(jī)的3D關(guān)系被確定途蒋,也就是說猛遍,其坐標(biāo)關(guān)聯(lián)于一個(gè)恰當(dāng)?shù)淖鴺?biāo)系(basis)。在計(jì)算機(jī)圖形中我們借助一個(gè)右手性的正交標(biāo)準(zhǔn)幀(right handed orthonormal frame),被稱為眼睛幀(eye frame)懊烤。我們將眼睛解讀為正看向這個(gè)幀的負(fù)z軸同時(shí)拍攝相片(參考圖示
)梯醒。眼睛幀(eye frame)通過某種(剛體-rigid body)
矩陣
和世界幀(world frame)關(guān)聯(lián):
在計(jì)算機(jī)程序中,我們會(huì)明確地存儲(chǔ)矩陣腌紧。
給定一個(gè)點(diǎn)
我們將稱為物體坐標(biāo)(object coordinates)茸习,將
稱為世界坐標(biāo)(world coordinates),將
稱為眼睛坐標(biāo)(eye coordinates)壁肋。我們借用下標(biāo)“
”用于物體坐標(biāo)(object coordinates)号胚,“
”下標(biāo)用于世界坐標(biāo)(world coordinates),“
”下標(biāo)用于眼睛坐標(biāo)(eye coordinates)浸遗。如此我們可以表達(dá)下面關(guān)系
最終猫胁,正是這些眼睛坐標(biāo)(eye coordinates)指定了每個(gè)頂點(diǎn)(vertex)在被渲染圖像中所出現(xiàn)的位置。因此跛锌,就如在第6章中所描述的弃秆,我們的渲染處理將需要計(jì)算每個(gè)頂點(diǎn)的眼睛坐標(biāo)(eye coordinates)。
Figure 5.1: 世界幀(world frame)用紅色表示髓帽,物體幀(objects frame)用綠色表示菠赚,而眼睛幀(eye frame)用藍(lán)色表示。眼睛正看向眼睛幀中朝向物體方向的負(fù)z軸氢卡。
5.2 任意移動(dòng)物體(Moving Things Around)
在一個(gè)交互式的3D程序中锈至,我們經(jīng)常想要借助某種剛體變換(rigid body transformation)在空中來回移動(dòng)物體和眼睛(視野方位)。現(xiàn)在我們討論這種行為如何被實(shí)現(xiàn)译秦。
5.2.1 移動(dòng)一個(gè)物體(Moving an Object)
我們通過恰當(dāng)?shù)馗挛矬w所對(duì)應(yīng)的幀(frame)的方式移動(dòng)一個(gè)物體峡捡,這可以通過更新其矩陣O的方式被表示。
比方說筑悴,我們希望關(guān)聯(lián)于某種幀(frame)對(duì)一個(gè)物體幀(object frame)
應(yīng)用變換
们拙,就如在方程(4.1)中所示,我們可以取得如下推導(dǎo)
所以在代碼中我們將變換實(shí)現(xiàn)為阁吝。
什么是的自然選擇砚婆?最明顯的選擇會(huì)是關(guān)聯(lián)于
自身應(yīng)用變換到
上。不幸的是突勇,這意味著被使用的軸會(huì)是相對(duì)于物體本身的那些軸装盯。“向右”會(huì)在物體的右側(cè)方向甲馋,這不會(huì)在被觀察的圖像中對(duì)應(yīng)任何實(shí)際的方向埂奈。我們可能嘗試通過關(guān)聯(lián)于
變換
。這會(huì)修復(fù)軸相關(guān)問題但是卻生成了另一個(gè)問題定躏。當(dāng)我們旋轉(zhuǎn)物體账磺,它會(huì)圍繞眼睛幀(eye frame)的原點(diǎn)做環(huán)繞運(yùn)動(dòng)芹敌。但是我們通常發(fā)現(xiàn)圍繞物體自己的中心旋轉(zhuǎn)才更自然,這個(gè)中心我們認(rèn)為是
的原點(diǎn)垮抗。參考圖示
氏捞。
要修復(fù)這兩種問題,我們可以生成一個(gè)新的幀(frame)冒版,其擁有物體(object)幀的原點(diǎn)液茎,還有眼睛(eye)幀的軸。要獲得這個(gè)幀辞嗡,讓我們將我們已有的矩陣分解如下
這里代表矩陣A的平移因子豁护,
代表矩陣A的旋轉(zhuǎn)因子,就如在方程(3.3)中一樣欲间。我們隨后可以看到想要的輔助幀(auxiliary frame)應(yīng)該為如下形式
這個(gè)幀(frame)通過始于世界坐標(biāo)系(world coordinate system),然后平移其到物體幀(object‘s frame)的原點(diǎn)(從左到右讀断部,也就是說猎贴,依次經(jīng)歷關(guān)聯(lián)于局部的變換解讀),再然后圍繞這個(gè)點(diǎn)旋轉(zhuǎn)從而達(dá)到與眼睛幀(eye)的軸方向?qū)R蝴光。(參考圖示)她渴。
因此,對(duì)于這種物體運(yùn)動(dòng)(object motion)蔑祟,方程式(5.1)中矩陣A應(yīng)該為趁耗。
有一種完成相同效果的替代計(jì)算。舉個(gè)例子疆虚,假設(shè)苛败,我們希望借助一個(gè)旋轉(zhuǎn)軸圍繞其自身的中心旋轉(zhuǎn)一個(gè)物體,這個(gè)旋轉(zhuǎn)軸具有關(guān)聯(lián)于
的坐標(biāo)
径簿。(在上面計(jì)算中我們其實(shí)用
獲得了一個(gè)矩陣M罢屈,然后和一個(gè)合適的矩陣A一起,我們更新物體矩陣
篇亭。)我們可以首先計(jì)算
缠捌,
的關(guān)聯(lián)于
的坐標(biāo)。然后將
代入方程式(2.5)中译蒂,我們可以得到一個(gè)矩陣
曼月,這個(gè)矩陣直接表達(dá)了關(guān)聯(lián)于
的我們所要求的旋轉(zhuǎn)。在這種情形中柔昼,我們可以更新物體矩陣(object's matrix)為:
Figure 5.2: 當(dāng)我們移動(dòng)鼠標(biāo)到右側(cè)哑芹,我們想讓物體圍繞其中心和沿著眼睛的軸方向旋轉(zhuǎn)。
Figure 5.3: 輔助幀(auxiliary frame) 擁有的原點(diǎn)(origin)和的軸方向(axes)岳锁。 軸指向頁面中绩衷,已經(jīng)被抑制(沒有繪制)蹦魔。
5.2.2 移動(dòng)眼睛(視角)(Moving the Eye)
另一種我們希望進(jìn)行的操作是移動(dòng)眼睛到不同的視角。這會(huì)涉及改動(dòng),在程序中具體通過更新矩陣
來達(dá)到目的咳燕。再一次勿决,我們可以挑選一個(gè)合適的坐標(biāo)系,關(guān)聯(lián)于這個(gè)坐標(biāo)系我們執(zhí)行
的更新招盲,就如之前我們?cè)谖矬w上所做的操作低缩。
一種選擇是使用和上面相同的輔助坐標(biāo)系。在這種情形中曹货,眼睛會(huì)圍著物體的中心環(huán)繞運(yùn)動(dòng)咆繁。
另一種有效的選擇是關(guān)聯(lián)于眼睛自身的幀(frame)變換。這會(huì)建模自我運(yùn)動(dòng)(ego-motion)顶籽,就如轉(zhuǎn)動(dòng)你的頭部玩般。這通常被用于控制第一人稱(first-person)運(yùn)動(dòng)。在這種情形中矩陣E會(huì)被更新為
5.2.3 Lookat(盯著看)
本節(jié)有一些錯(cuò)誤礼饱,已經(jīng)根據(jù)本書的errata改正坏为。
有時(shí),特別是針對(duì)靜態(tài)圖像(static images)時(shí)镊绪,直接描繪出眼睛幀會(huì)很便利匀伏,通過指定眼睛的位置
,和一個(gè)眼睛正死盯著的點(diǎn)
,還有一個(gè)“上方矢量(up vector)"
用于描述眼睛上方的方向蝴韭。這些點(diǎn)和矢量通過變量
,
和
被給出够颠,它們的坐標(biāo)關(guān)聯(lián)于
。假定這種輸入榄鉴,進(jìn)行下面的計(jì)算
然后矩陣可以被定義為:
注:此處的眼睛矩陣
并不是通常在CG中的View矩陣履磨,View矩陣一般為
。
5.3 伸縮變換(Scales)
目前為止牢硅,我們已經(jīng)將我們的世界認(rèn)為是由運(yùn)動(dòng)的物體組成蹬耘,每個(gè)物體都有一個(gè)由其自身的剛體矩陣所表達(dá)的正交標(biāo)準(zhǔn)幀(orthonormal frame) 。我們將關(guān)注點(diǎn)限制到正交標(biāo)準(zhǔn)幀以便平移和旋轉(zhuǎn)矩陣可以像我們預(yù)期它們的行為那樣工作减余。
當(dāng)然综苔,要建模物體,我們當(dāng)然想同時(shí)應(yīng)用伸縮位岔。例如如筛,我們想要將一個(gè)橢球體建模為一個(gè)被擠壓的球體。一種處理方式是讓這個(gè)物體同時(shí)擁有一個(gè)伸縮矩陣(scaled matrix)抒抬。然后被伸縮的物體幀(非正交標(biāo)準(zhǔn)化的)被確定為
杨刨。這種方式中我們?nèi)匀幌裆厦嬉粯油ㄟ^更新矩陣
移動(dòng)物體。要繪制這個(gè)物體擦剑,我們使用矩陣
將“伸縮的物體坐標(biāo)”變換為眼睛坐標(biāo)妖胀。
5.4 層級(jí)體系(Hierarchy)
經(jīng)常將一個(gè)物體(object)當(dāng)作由一些固定的或可活動(dòng)的多個(gè)子-物體(sub-objects)組裝而成芥颈,這種觀點(diǎn)其實(shí)很有用。每個(gè)子-物體可以擁有自己的正交標(biāo)準(zhǔn)幀(orthonormal frame)赚抡,比如說爬坑。(同時(shí)還有伸縮幀-scaled frame)。然后我們可以用其自己的坐標(biāo)系存儲(chǔ)這個(gè)子-物體的頂點(diǎn)(vertex)涂臣。給定這個(gè)層次體系盾计,我們想擁有這種能力-即可以輕松以整體建模物體的運(yùn)動(dòng),同時(shí)也可以獨(dú)立建模子-物體的運(yùn)動(dòng)赁遗。
例如署辉,當(dāng)建模帶有移動(dòng)肢體的機(jī)器人時(shí),我們可以借助一個(gè)物體幀(object)和伸縮物體幀(scaled object frame)表達(dá)軀干岩四,一個(gè)子-物體幀(sub-object frame)表達(dá)一個(gè)可以轉(zhuǎn)動(dòng)的肩膀哭尝,還有一個(gè)子-子-物體幀(sub-sub-object frame)表達(dá)上臂(其和肩膀一起運(yùn)動(dòng))。(參考圖示)剖煌。
Figure 5.4: 在本例中刚夺,綠色的幀(frame)為物體幀(object frame) ,灰色的幀為伸縮物體幀(scaled object frame)末捣。一個(gè)單位立方體(unit cube)的坐標(biāo)在中被繪制從而形成一個(gè)矩型(長(zhǎng)方形)的軀干。矩陣可以被改變用于移動(dòng)整個(gè)機(jī)器人创橄。青色的幀為右肩幀(right shoulder frame)箩做。矩陣A中的旋轉(zhuǎn)因子可以被改變用于旋轉(zhuǎn)整個(gè)右臂。淺藍(lán)色幀為右上臂幀(right upper arm frame)妥畏。紅色幀為伸縮(scaled)右上臂幀邦邦。一個(gè)單位球體的坐標(biāo)在中繪制形成了橢球體形狀的右上臂。為右肘幀(right elbow frame)醉蚁。矩陣C中的旋轉(zhuǎn)因子可以被改變用于旋轉(zhuǎn)右下臂(right lower-arm)燃辖。和分別為正交標(biāo)準(zhǔn)和伸縮的右下臂幀用于繪制下臂。幀為左肩幀(left shoulder frame)网棍。
當(dāng)我們通過更新矩陣移動(dòng)整個(gè)物體黔龟,我們想讓所有的物體(組件)更加協(xié)調(diào)一致(參考圖示
)。要獲得這種行為滥玷,我們借助一個(gè)將其和物體幀(object’s frame)聯(lián)系在一起的剛體矩陣表達(dá)了子物體幀(sub-object‘s frame)氏身。因此,我們存儲(chǔ)了一個(gè)剛體矩陣(rigid body matrix)
惑畴,我們將其解讀為定義了這種關(guān)系:
蛋欣,同時(shí)還有一個(gè)伸縮矩陣
,其定義了伸縮的子物體幀(sub-object frame)為
如贷。要重新定位在這個(gè)物體內(nèi)的子-物體(sub-object)陷虎,所有我們需要做的就是更新矩陣
到踏。要繪制子-物體(sub-object),我們使用矩陣
尚猿,其變換“伸縮的子-物體坐標(biāo)”為眼睛坐標(biāo)(eye coordinates)窝稿。很清晰地,這種思路可以被遞歸嵌套谊路,同時(shí)我們可以表達(dá)一個(gè)子-子-物體(sub-sub-object)為
,以及一個(gè)伸縮的子-子-物體為
。
在我們的機(jī)器人例子中惨恭,我們使用了為右肩的幀(frame)封寞,
為右上臂的幀,還有
為右肘幀趟薄。
和
分別是右下臂的正交標(biāo)準(zhǔn)幀和伸縮幀。
要移動(dòng)整個(gè)機(jī)器人荷并,我們更新其矩陣(參考圖示
)赏枚。要在肩膀處彎曲右臂,我們更新其
矩陣(參考圖示
)脓规。要在肘部彎曲右臂栽连,我們更新其
矩陣(參考圖示
)。
Figure 5.5: 要移動(dòng)整個(gè)機(jī)器人侨舆,我們更新矩陣秒紧。
Figure 5.6: 要在肩部彎曲胳膊,我們更新矩陣挨下。
Figure 5.7: 要彎曲肘部熔恢,我們更新矩陣。
經(jīng)常臭笆,一個(gè)矩陣棧數(shù)據(jù)結(jié)構(gòu)(matrix statck data structure)可以被用來跟蹤表達(dá)當(dāng)前被繪制子-物體(sub-object)的矩陣叙淌。在這種矩陣棧結(jié)構(gòu)中,push(M)
操作生成一個(gè)新的“最頂部”矩陣愁铺,它只是之前最頂部矩陣的一份拷貝(copy)凿菩,隨后其被用參數(shù)矩陣M右乘這個(gè)新頂部矩陣。pop
操作移除棧的最頂層(topmost layer)帜讲。當(dāng)在層次體系中“下降”到一個(gè)子-物體(sub-object)衅谷,push操作被執(zhí)行。當(dāng)我們從
當(dāng)前層次返回父級(jí)層次似将,矩陣被從棧中彈出获黔。
例如蚀苛,在偽碼(pseudo-code)中,我們將上面的機(jī)器人繪制為玷氏。
...
matrixStack.initialize(inv(E));
matrixStack.push(O);
matrixStack.push(O’);
draw(matrixStack.top(), cube); \\軀干(body)
matrixStack.pop(); \\O’
matrixStack.push(A);
matrixStack.push(B);
matrixStack.push(B’);
draw(matrixStack.top(),sphere); \\上臂(upper arm)
matrixStack.pop(); \\B’
matrixStack.push(C);
matrixStack.push(C’);
draw(matrixStack.top(),sphere); \\下臂(lower arm)
matrixStack.pop(); \\C’
matrixStack.pop(); \\C
matrixStack.pop(); \\B
matrixStack.pop(); \\A
\\當(dāng)前頂部矩陣為inv(E)*O(current top matrix is inv(E) * O)
\\現(xiàn)在我們可以繪制另一個(gè)手臂
matrixStack.push(F);
...
這種層次體系關(guān)系(hierarchical relations)可以被硬編碼到你的程序中堵未,就如在上面的偽碼中,或者被表示為某種被稱為場(chǎng)景圖(scene graph)的鏈接樹(linked tree)數(shù)據(jù)結(jié)構(gòu)盏触。