《3D Math Primer for Graphics and Game Development》读书笔记1
《3D Math Primer for Graphics and Game Development》讀書筆記1
本文是《3D Math Primer for Graphics and Game Development》第一版的讀書筆記。第二版貌似還沒(méi)有中文版。
本書網(wǎng)站gamemath.com。中文版居然給了翻譯公司的網(wǎng)址,而且里面還什么有用的都沒(méi)有,囧。
第2章 笛卡爾坐標(biāo)系統(tǒng)
左手坐標(biāo)系的記憶方法
伸出左手,手指依次是(1)大拇指、(2)食指、(3)中指;坐標(biāo)軸按字母表依次是(1)X軸、(2)Y軸、(3)Z軸。他們分別對(duì)應(yīng)起來(lái),用左手?jǐn)[成下圖的樣子(不錯(cuò)的pose啊),就是左手坐標(biāo)系。
右手坐標(biāo)系的記憶方法
同上,用右手就行了。
約定俗成和習(xí)慣
傳統(tǒng)的計(jì)算機(jī)圖形學(xué)使用左手坐標(biāo)系,線性代數(shù)則傾向于右手坐標(biāo)系。
兩種坐標(biāo)系沒(méi)有優(yōu)劣之分,只是使用習(xí)慣不同。
本書使用左手坐標(biāo)系。
第3章 多坐標(biāo)系
攝像機(jī)坐標(biāo)系
本書約定的攝像機(jī)坐標(biāo)系,攝像機(jī)在原點(diǎn),X軸向右,Z軸向前,Y軸向上,如下圖所示。
許多圖形學(xué)書中習(xí)慣使用右手系,Z軸向外,即從屏幕指向讀者。
坐標(biāo)系變換
坐標(biāo)系變換的意思:知道某一點(diǎn)P在坐標(biāo)系A(chǔ)中的坐標(biāo),如何獲取P在另一坐標(biāo)系B中的坐標(biāo)?
只需在坐標(biāo)系A(chǔ)中定位坐標(biāo)系B(描述B的原點(diǎn)和軸在A中的值)。后文會(huì)詳述。
包圍盒
向量軸對(duì)齊包圍盒是axially aligned bounding box(AABB)的翻譯。我就是覺(jué)得包圍盒這個(gè)翻譯很不錯(cuò)。
第4章 向量
相對(duì)位置
"50英里每小時(shí)的速度向北"能用向量表示。
向量能描述的是相對(duì)位置。相對(duì)位置的想法是很直接的:某個(gè)物體的位置,能通過(guò)描述它與已知點(diǎn)之間的相對(duì)關(guān)系來(lái)指明。
由此引出一個(gè)問(wèn)題,這些"已知"點(diǎn)在哪兒?什么是"絕對(duì)"位置?令人吃驚的是不存在這樣的東西。因?yàn)樵诿枋鲆粋€(gè)點(diǎn)的位置時(shí),總要描述它和其它一些點(diǎn)的關(guān)系。這就沒(méi)完沒(méi)了了。
既然"已知"點(diǎn)不存在,那么如何通過(guò)所謂的"已知"點(diǎn)來(lái)描述位置呢?我的思路是:假設(shè)存在一個(gè)已知點(diǎn)的位置。假設(shè)已經(jīng)找到了一個(gè)已知點(diǎn),這樣就不必?zé)o限地去追溯"已知"點(diǎn)了。
相對(duì)論的一個(gè)重要觀點(diǎn)就是不存在絕對(duì)參考系。
第5章 向量運(yùn)算
向量和點(diǎn)的關(guān)系
向量[x, y]描述了原點(diǎn)到點(diǎn)(x, y)的位移量。
向量和點(diǎn)在概念上不同,而在數(shù)學(xué)上等價(jià)。
等價(jià)是什么意思?等價(jià)就是兩者存在一一對(duì)應(yīng)的關(guān)系。一一對(duì)應(yīng)是什么意思?就是即使你和我毫不相干,但是你有一個(gè)什么東西,我就有一個(gè)相應(yīng)的什么東西;反過(guò)來(lái)也一樣。比如你在照鏡子,你看到鏡子里的人臉上粘個(gè)米粒,就知道自己什么情況了。
向量投影
給定兩個(gè)向量v和n,可以把v分成兩部分:v||和v⊥。它們分別平行和垂直于n, 并滿足v = v|| + v⊥。我們把平行分量v||稱作v在n上的投影。
投影的計(jì)算公式:
垂直分量的公式:
后文會(huì)有很多地方用到這兩個(gè)公式。總之你知道有這兩個(gè)公式存在就行了,需要的時(shí)候拿來(lái)用。畢竟不需要做數(shù)學(xué)家。
第6章 3D向量類
類接口
好的類設(shè)計(jì)首先要回答下列問(wèn)題:"這個(gè)類將提供什么操作?"、"在哪些數(shù)據(jù)上執(zhí)行這些操作?"
從這些代碼和設(shè)計(jì)思路中就可以感受到作者的認(rèn)真態(tài)度和深厚功底。
設(shè)計(jì)決策
如果世界不超過(guò)1英里,那么32位的float類型就足夠,因?yàn)?4位尾數(shù)能提供1/250英寸的精度。
如果世界超過(guò)200英里(321.8688千米),比如整個(gè)江蘇省,那么32位float就不夠了。
不存在Point3類
有了Vector3類,就不需要Point3類。避免重復(fù)代碼以及滿世界的向量與點(diǎn)的轉(zhuǎn)換。
關(guān)于優(yōu)化
過(guò)早的優(yōu)化是一切罪惡的根源。優(yōu)化那些非瓶頸的代碼,使代碼復(fù)雜化,卻沒(méi)有得到相應(yīng)的回報(bào)。
在過(guò)去,定點(diǎn)數(shù)是一種優(yōu)化技術(shù)。當(dāng)今的處理器已經(jīng)可以快速處理浮點(diǎn)數(shù),這個(gè)技術(shù)就不需要了。
不要為了2%的優(yōu)化付出100%的代碼復(fù)雜性。
簡(jiǎn)單點(diǎn)說(shuō),就是別優(yōu)化,我的技術(shù)水平?jīng)]那么高。
第7章 矩陣
矩陣用來(lái)描述兩個(gè)坐標(biāo)系間的關(guān)系,通過(guò)定義一種運(yùn)算來(lái)將一個(gè)坐標(biāo)系中的向量/點(diǎn)轉(zhuǎn)換到另一個(gè)坐標(biāo)系中。換句話說(shuō),就是已知一個(gè)向量/點(diǎn)在坐標(biāo)系A(chǔ)中的坐標(biāo),又知坐標(biāo)系A(chǔ)和坐標(biāo)系B的關(guān)系,求其在坐標(biāo)系B中的坐標(biāo)。
向量是標(biāo)量的數(shù)組,矩陣是向量的數(shù)組。
矩陣的下標(biāo)從1開(kāi)始。
矩陣乘法
記r×n矩陣A與n×c矩陣B的乘積為C。C的任意元素Cij如下:
矩陣乘法設(shè)計(jì)成這樣,是因?yàn)橛袑?shí)際意義,數(shù)學(xué)上也有研究?jī)r(jià)值。或者說(shuō),正是因?yàn)樗从沉爽F(xiàn)實(shí)世界的某些東西,才會(huì)有數(shù)學(xué)意義。
本書給了一種非常好的記憶方法:
我擴(kuò)展了一下,可以將A的各個(gè)列拆開(kāi),同時(shí)將B的各個(gè)行拆開(kāi):
變成下圖所示的樣子:
可以看到,矩陣的乘法運(yùn)算,可以把A的各列拆開(kāi),B的各行拆開(kāi),分別運(yùn)算,最后相加。拆分時(shí),只要A的列和B的行的拆分方式相同即可。
還有另一種拆法:把A的各行拆開(kāi),B的各列拆開(kāi),分別運(yùn)算,最后拼起來(lái)。
而且,還可以同時(shí)進(jìn)行這兩種拆分。這時(shí),你可以看做先進(jìn)行第一種拆分,然后進(jìn)行第二種拆分,這樣(對(duì)我來(lái)說(shuō))比較容易理解。這樣就能理解矩陣分塊計(jì)算的原理。
約定和習(xí)慣
本書默認(rèn)使用行向量進(jìn)行與矩陣的運(yùn)算。
DirectX使用的是行向量。
OpenGL使用的是列向量。
線性變換
線性變換保留了模型中原有的直線和平行線,原點(diǎn)也保持不動(dòng)。長(zhǎng)度、角度、體積可能會(huì)改變。從非技術(shù)意義上說(shuō),線性變換可能"拉伸"坐標(biāo)系,但不會(huì)"彎曲"或"卷折"坐標(biāo)系。
旋轉(zhuǎn)、縮放、投影、鏡像是線性變換。
仿射(線性變換后平移)不是線性變換。
方陣能描述線性變換。
矩陣運(yùn)算和3D變換
設(shè)有一組基向量p0=(1, 0, 0),q0=(0, 1, 0),r0=(0, 0, 1),此時(shí)向量v=(x, y, z)就是v在p0=(1, 0, 0),q0=(0, 1, 0),r0=(0, 0, 1)這個(gè)坐標(biāo)系里的坐標(biāo),即有v = xp0 + yq0 + zr0。
設(shè)p、q、r為任意一組基向量。例如p=(1, 0, 0),q=(0, 1, 0),r=(0, 0, 1)(互相垂直);或p=(0.8, 0.6, 0),q=(-0.6, 0.8, 0),r=(0, 0, 1) (互相垂直);或p=(1/√5)(2,-1,0),q= (1/√45)(2,4,5),r= (1/3)(1,2,-2) (互相垂直)或p=(1, 1, 1-√2 ),q=(1-√2, 1, 1),r=(1, 1-√2, 1)(并非互相垂直)……
然后,我們用p、q、r構(gòu)造矩陣。沒(méi)什么理由,就這么做了。
來(lái)看看向量v=(x, y, z)乘以矩陣會(huì)出現(xiàn)什么?
從左邊到第一個(gè)等號(hào)右邊,說(shuō)明這個(gè)乘法運(yùn)算給v賦予了新的坐標(biāo)值。廢話。
從第一個(gè)等號(hào)右邊到第二個(gè)等號(hào)右邊,說(shuō)明這個(gè)新的坐標(biāo)值與基向量p、q、r的關(guān)系等同于v與原始基向量p0=(1, 0, 0),q0=(0, 1, 0),r0=(0, 0, 1)的關(guān)系,這就是新坐標(biāo)值的意義所在。
這也是矩陣乘法設(shè)計(jì)成這樣的價(jià)值所在。
所以,把3×3矩陣M的3行看做轉(zhuǎn)換后的3個(gè)基向量,那么任意一個(gè)1×3的行向量v乘以M,就得到了v轉(zhuǎn)換后的坐標(biāo)。這就是說(shuō),乘以該矩陣就相當(dāng)于執(zhí)行了一次坐標(biāo)轉(zhuǎn)換。若有aM=b,我們就可以說(shuō),M將a轉(zhuǎn)換到b。
如何建立需要的矩陣?
上一節(jié)說(shuō)明了,3×3矩陣的每一行都能解釋為轉(zhuǎn)換后的基向量。初始坐標(biāo)系中的向量/點(diǎn)經(jīng)過(guò)轉(zhuǎn)換,得到了各自新的坐標(biāo)值。那么,初始坐標(biāo)系中的基向量p0=(1, 0, 0),q0=(0, 1, 0),r0=(0, 0, 1)經(jīng)過(guò)轉(zhuǎn)換,得到的新坐標(biāo)值是?
觀察這三個(gè)式子,你會(huì)發(fā)現(xiàn)新的基向量恰好組成了我們需要的轉(zhuǎn)換矩陣。
一般情況下,我們是不能預(yù)先得到轉(zhuǎn)換矩陣的。而三個(gè)式子就給出了獲取轉(zhuǎn)換矩陣的方法。就是說(shuō),只要我們能先用別的什么方法求出新的基向量的坐標(biāo)值,就能拼出轉(zhuǎn)換矩陣,然后就可以從任意一個(gè)向量/點(diǎn)的初始坐標(biāo)值得到其新的坐標(biāo)值!
總之,矩陣等價(jià)于變換后的基向量。
2D示例
比如這個(gè)矩陣:
這個(gè)矩陣代表的變換是什么?
首先,從矩陣中抽出基向量p和q:
下圖展示了p0=(1, 0), q0=(0, 1)轉(zhuǎn)換到p,q后的樣子:
加個(gè)圖片會(huì)看起來(lái)更直觀:
“不幸的是,沒(méi)有人能告訴您矩陣像什么——您必須自己去感受。”
總結(jié)
以上是生活随笔為你收集整理的《3D Math Primer for Graphics and Game Development》读书笔记1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Exchange2010恢复已禁用邮箱后
- 下一篇: push.sh