Abstract
我在入門計算機圖形學過程中,許多文獻書籍在解釋成像原理時總是單刀直入地將齊次坐標捆綁在透視投影的推導中,令我一時難以接受如此“新鮮”的概念;在很長一段時間里,齊次坐標對我來說是一種很神秘的符號,它的 \(w\) 分量是如此抽象而晦澀。
於是在查閱大量內外網資料后,我對齊次坐標所構建的系統有了認知。我相信這篇小文能對理解計算機世界中的投影幾何的本質有一定的幫助。本文我會循序漸進構建一些知識體系,並用一絲絲拙略的數學口吻來描述;若有任何不恰當的錯誤,還請勞煩您向我指正!
投影幾何 Projection Geometry
歐幾里得幾何學很好地描述了我們的三維世界,然而當考慮到相機的成像過程時,很明顯歐幾里得幾何不夠用:長度和角度不再可靠,平行線可能會相交。所以有了投影幾何,它是對歐幾里得幾何的擴展。
筆者寄語:當你理解這篇文章的每個部分后,我相信你至少能在面對與投影幾何相關的工作(圖形、游戲編程)時有足夠的底氣。文中只有一點點數學計算,相信難不倒聰慧的你 😃
投影平面 Projection Plane
當你端着畫板對風景進行寫生、用相機記錄美好瞬間時,你無不正與投影幾何所打交道。
寫生時,投影平面便是你的畫板;假設你是一個神人,你握着鉛筆的那只手上長了一只眼睛,這只眼睛甚至能透視 --- 穿過畫板看到目標景觀,並精確捕捉顏色,指揮手來繪畫。
此時我們便說,“眼睛” 透視 畫板,將看到的風景顏色投影到了 投影 平面上。
我們將這種十分直白的現象抽象一下:
存在一個視點(相機),一個投影平面,和需要被投影至面上的點;另外,我們習慣於將視點置於經典笛卡爾坐標系的原點 \(O\) 。
投影幾何點 Points in Projective Geometry 與齊次坐標 Homogeneous Coordinates
齊次坐標
三維空間中點的坐標通常用 \((x, y, z)\) 表示;而齊次坐標便是在當前維度的坐標表示下,為其擴展一個分量 \(w\) ,使其變為 \((x, y, z, w)\) 。
我們做本文第一個重要的約定:
齊次坐標只有在應用於 投影幾何系統中的點 時,才具有實際意義,並且這種點稱為 “投影幾何點” ;
而當應用於普通坐標系統中的點時,齊次坐標便不具有實際意義,並且這種點稱為 “普通點” 。
旁注:本文的“齊次坐標”與線性變換中的“齊次坐標”體現的功能性不同,請不要迷失
區分投影幾何點與普通點
為了方便計算機處理,我們將齊次坐標表示均應用於 “普通點” 與 “投影幾何點”,並用一種方法對它們進行區分。
現在,我們做本文第二個重要的約定:(在閱讀本文時,請一定謹記這個約定,它將成為你區分投影幾何點 / 普通點的功臣)
有一個齊次坐標表示的點 \(P(x, y, z, w)\) ,當且僅當 \(P\) 滿足以下條件:
- 當 \(w = 1\) 時 ,\(P\) 正好位於投影平面 \(z = n\) 上
此時將 \(P\) 稱為 投影幾何點 ;任何不滿足此條件的點,一律稱為 普通點 。以下是一個直觀例子:
顯然,只有點 \(P\) 滿足條件,所以它是一個 投影幾何點 ,而 \(A\) 、\(B\) 為 普通點。
此時你一定會發問:“什么叫 '當 \(w = 1\) 時' ?\(w\) 依據什么而改變?” 那么,我將為你解開疑惑。
\(w\) 的功能
有一 投影幾何點 \(P(x, y, n, 1)\) 位於投影平面 \(z = n\) 上。一條視線從視點 \(O\) 出發,穿過 \(P\) 並直入深邃的空間中;
我們將 \(P\) 沿着 \(l\) 往上走一段距離,變成 \(P^{'}(x^{'}, y^{'}, m, w^{'})\)
我們離近點看,爭取將 \(P^{'}\) 算出來:(推導稍許冗長,你可以選擇直接看結論,但我建議你了解其中的細節 😃 )
分別做點 \(P\) 、\(P^{'}\) 的垂線 \(PC\) 、\(P^{'}D\) ,並分別與平面 \(y = 0\) 交於點 \(C\) 、\(D\) ;再於 \(z\) 軸上找到 \(A\) 、\(B\) ,分別做它們的垂線,與點 \(C\) 、\(D\) 相交,則 \(OA = n\) ,\(OB = m\)。
由相似三角形關系:
\( \triangle OAC \sim \triangle OBD\\ \Rightarrow \frac{AC}{BD} = \frac{OA}{OB}\\ \Rightarrow BD = P^{'}_{x} = \frac{AC \cdot OB}{OA} = P_{x} \cdot \frac{m}{n}\ \ \ (1) \)
由平行關系:
\( AC\ \verb|//|\ BD\\ \Rightarrow \frac{OC}{OD} = \frac{OA}{OB}\ \ \ (2) \)
由相似三角形關系:
\( \triangle OCP \sim \triangle ODP^{'}\\ \Rightarrow \frac{PC}{P^{'}D} = \frac{OC}{OD}\\ \Rightarrow P^{'}D = P^{'}_{y} = \frac{PC \cdot OD}{OC} = P_{y} \cdot \frac{OD}{OC}\ \ \ (3) \)
聯立 \((2)(3) \Rightarrow P^{'}_{y} = P_{y} \cdot \frac{OB}{OA} = P_{y} \cdot \frac{m}{n}\ \ \ (4)\)
有了結論 \((1)(4)\) ,我們便能寫出點 \(P^{'}\) 的坐標:\(P^{'} = (x \cdot \frac{m}{n},\ y \cdot \frac{m}{n},\ m,\ w^{'})\) 。呼,推導真費頭發,我保證這是最后一次了。
對比一下 \(P\) 與 \(P^{'}\) 的坐標,我們能得出什么結論:
\(P^{'} = \frac{m}{n} \cdot P\) ,也即是,點 \(P^{'}\) 與點 \(P\) 關於 \(\frac{m}{n}\) 線性相關。現在你要問我 \(w^{'}\) 該變成什么,我會毫不猶豫地回答:\(\frac{m}{n}\) :
\(P^{'} = (x \cdot \frac{m}{n},\ y \cdot \frac{m}{n},\ m,\ \frac{m}{n})\)
現在你應該對分量 \(w\) 有某種微妙的認知,它並不是一個空間上的維度,而是一個線性縮放的因子,不是嗎?
當點 \(P\) 離開平面 \(z = n\) 在視線 \(l\) 上移動時,\(w\) 將成為一個縮放因子,線性地改變 \(P\) 各分量的值。你或許會嘲笑我說:"點P離開了平面,w又變成了一個不是1的值,那它豈不變成了一個普通點?"
現在,就是展示投影幾何威力的時刻。 想象點 \(P^{'}\) 就是我們想寫生的景物,此時你的神奇的手使出絕技:“吸星大法!” --- 你對 \(P^{'}\) 的所有分量同時除以它的 \(w\) ,\(P^{'}\) 瞬間變成了 \(P\) ,並被“吸”回投影平面 \(z = n\) ------- 這便是大名鼎鼎的 透視除法 !透視除法的目標便是將 投影幾何點 的 \(w\) 分量變為 \(1\) ,這樣點就能回到投影平面上。
而從另一個角度看,\(P \rightarrow P^{'}\) 之間可通過除法相互轉換,推廣到視線 \(l\) 上的所有點,它們都能通過 \(P\) 乘一個縮放因子來相互轉化。因此我們進行第三次約定:
-
我們說 投影幾何系統中的直線 指的是視線(穿過原點的任意直線)
-
在投影幾何中,每一條直線(視線)都可當作一個點( 投影幾何點 )
-
在同一條視線上,所有點其實都是同一個點
因為只有視線符合“投影”的語境:視線要么與投影平面有一個交點,要么平行於投影平面,無任何交點,不是嗎?
普通點
只有在規定好了一個投影平面 \(z = n\) 時,才能構建與它配套存在的 投影幾何點(視線):
\(P = (x, y, n, 1)\) 或 \(P = (\frac{m}{n}x, \frac{m}{n}y, m, \frac{m}{n})\)
面對點 \(A = (2, 0, n, 3)\) 時,你或許會說“ \(A\) 正好在 \(z = n\) 上,它看起來也是一個 投影幾何點 呀”。
但你若換個角度,將 \(A\) 除以它的 \(w\) 分量變為
\(A^{'} = (\frac{2}{3}, 0, \frac{n}{3}, 1)\)
呃, \(w = 1\) ,你想到了什么?
沒錯,在由圍繞投影平面 \(z = n\) 架構的投影幾何系統中, \(A\) 是一個 普通點 ;而在由圍繞 \(z = \frac{n}{3}\) 構建的投影幾何系統中, \(A\) 卻是一個關於 \(z = \frac{n}{3}\) 的 投影幾何點 。
於是我們便可以得出結論, \(A\) 之所以為一個 普通點,是因為它在我們規定的與 \(z = n\) 相關的投影幾何系統中不適用 ------ 為它執行透視除法后,它不能回到 \(z = n\) 上。所謂 普通點 與 投影幾何點 ,均是由人為規定,存在於一定的參照條件下(投影平面)而自洽的;
但若離開 “我欲'透視'並將某物'投影'到我的畫板上” 這樣的語境時,將不會存在投影平面,也不用區分 普通點 與 投影幾何點。 投影幾何系統也瞬間崩塌,所有處於三維笛卡爾空間中的點均恢復為最為普通的,也是我們最為熟知的經典笛卡爾坐標點。
透視除法矩陣 Perspective Division Matrix
很好,我們現在能區分 普通點 與 投影幾何點。我們在之前還說
透視除法的目標便是將 投影幾何點 的 \(w\) 分量變為 \(1\),這樣點就能回到投影平面上。
之前的討論中,我們為透視除法賦予了一種操縱幾何變換關系的能力,它只能應用於 投影幾何點 。
但回到我們工作 / 學習的環境,計算機在對齊次坐標進行線性變換計算時不可能完美地將所有頂點處理成 投影幾何點 ;事實上,頂點在一開始或被計算的過程中,大部分都是 普通點 ,它們沒辦法通過除以 \(w\) 來投影到我們規定好的平面上。
覺得熟悉嗎?在工作 / 學習環境中,投影平面是 \(z = near\) ,我們輸入的三角面片的世界坐標一般都如圖中 \(ABC\) 這樣。顯而易見,它們均是 普通點;但我們又想將它們投射到 \(z = near\) 上,然而透視除法無法應用於這樣的點。
所以人們想到一種辦法,來將一個 普通點 變換到已構建好的投影幾何系統中,並讓它變為一個 投影幾何點 , 這樣一來,便可以順理成章地將它“吸”回投影平面。這便是 透視除法矩陣 的工作:
設已存在投影平面 \(z = n\) ,一 普通點 \(P(x, y, m, w)\) 。現在構建 透視除法矩陣:
\(\left[\begin{array}{cccc}1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & \frac{1}{n} & 0\end{array}\right]\left[\begin{array}{c}x\\y\\m\\w\end{array}\right] = \left[\begin{array}{c}x\\y\\m\\\frac{m}{n}\end{array}\right]\)
你會發現,該矩陣的效果僅為將比例 \(\frac{m}{n}\) 賦予 \(P\) 的 \(w\) 分量。要我來說,這個矩陣應該叫做 將普通點轉換為投影幾何點矩陣 (意思一下,不要當真)。
\(P\) 此時真的成為了 投影幾何點 --- 不信將它除以 \(w\) ,變為:
\(P = (\frac{n}{m}x,\ \frac{n}{m}y,\ n,\ 1)\)
很神奇,不是嗎?變換后的 \(P\) 能名正言順地應用透視除法並回到 \(z = n\) , \(w\) 還等於 \(1\) !
尾聲:無窮遠點 Points at Infinity / 齊次坐標的 \(z\rightarrow0\) 會怎樣
我們將投影平面畫得不那么秀氣一點。做一條垂直於 \(z = n\) 且穿過 \(P\) 的直線,以觀察當 \(P\) 朝着 \(P_{z} \rightarrow 0\) 的方向上移動時,會發生什么。
將 \(P\) 沿垂線后退一些,變為 \(P^{'}(x^{'}, y^{'}, m, w^{'})\) 。為了再次將 \(P^{'}\) 投影回去,對其應用透視除法矩陣,並執行透視除法,則 \(P^{'}\) 重新成為新投影點 \(P(\frac{n}{m}x,\frac{n}{m}y,n,1)\) ,同時視線 \(l\) 變為 \(l^{'}\) 。
當 \(P^{'}\) 越往里移動,投影點離投影屏幕中心 \(O^{'}\) 越來越遠;當 \(P^{'}_{z} \rightarrow 0\) 時,投影點與 \(O^{'}\) 的距離近乎無限大,且會收斂為視線 \(l^{''}\) 平行於投影屏幕的情形。此時我們說此投影點或者視線 \(l^{''}\) 是一個無窮遠點。
至此關於投影幾何的介紹基本完結。如果你覺得有什么遺漏或者錯誤,歡迎用博客園的評論或私信系統告訴我。
創作不易,轉載請注明出處 😃