- 投影變換
- 正投影
- 軸測、等軸測正投影
- 正投影座標系
- 裁剪視窗、正投影觀察體
- 正投影的規範化變換
- 斜投影
- 斜*行投影
- 斜等測、斜二測*行投影
- 斜*行投影變換
- 透視投影
- 投影參考點與觀察原點
- 座標變換
- 特殊透視投影
- 滅點
- 滅點與投影參考點
- 透視投影觀察體
- 透視投影變換矩陣
- 對稱透視投影椎體
- 斜透視投影稜臺
- 透視投影的規範化變換
投影變換
將物件描述從世界座標系變換到觀察座標系後,要將其投影到觀察*面,即投影變換。有2種投影方式:
-
*行投影(parallel projection),座標位置沿*行線變換到觀察*面。保持物件的比例不變,常用於輔助繪圖、設計生成工程圖。獲取物件*行檢視的方法有2種:1)沿垂直於觀察*面的直線投影;2)沿某傾斜角度投影到觀察*面。
-
透視投影(perspective projection),物件位置沿會聚到觀察*面後的一點(即投影參考點/投影中心)的直線,變換到投影座標系。透視投影不會保持物件比例,但真實感更好。
注意:概念上,投影變換指將物件變換到觀察*面;實際應用中,投影變換除了指將物件變換到觀察*面,還包括規範化變換。
線段\(P_1P_2\)的*行投影、透視投影示意圖:
正投影
物件沿與投影*面法向量N*行的方向,到投影*面上的變換N稱為正投影(orthogonal projection)或正交投影(orthographic projection)。
正投影:特殊的*行投影,投影線//投影*面法向量N。常用於生成物件的前檢視、側檢視、頂檢視,可用於建築和工程繪圖。
軸測、等軸測正投影
軸測正投影:
生成顯示物件多個側面的正投影,這些檢視稱為軸測(axonometric)正投影。
等軸測投影:
等軸測(isometric)投影是特殊軸測投影,其投影*面與每個座標軸的交點到原點距離相等。
常見等軸測投影:多個投影*面形成一個立方體,立方體8個頂點分佈在觀察座標系的8分象限。
正投影座標系
觀察座標系\(x_{view}y_{view}z_{view}\)下,如果投影方向//\(z_{view}\)軸,則任意點\((x,y,z)\)的投影座標\((x_p,y_p,z_p)\):
其中,\(z_{vp}\)為觀察*面位置(觀察*面⊥\(z_{view}\)軸)。\(z_p\)值被儲存,用於可見性檢測。
任一點到觀察*面的正交投影:
裁剪視窗、正投影觀察體
常用矩形裁剪視窗來模擬照相機的鏡頭,用於確定有多少場景要顯示。
OpenGL中,裁剪視窗位於觀察*面上,位置、大小由矩形左下角+右上角確定,其邊與觀察座標系\(x_{view}, y_{view}\)軸*行,即\(x_{view}y_{view}\)*面的正則矩形。裁剪視窗邊界限定了要顯示的場景內容的x、y範圍。
觀察*面上用觀察座標指定裁剪視窗:
∵正投影的投影線⊥觀察*面
∴裁剪視窗的4個邊界的投影線⊥觀察*面
此時,裁剪視窗的4個邊界的投影線形成一個無限的裁剪區域,即沒有頭尾的長方體,如下圖:
選擇1個或2個邊界*面(//觀察*面),為該(無限裁剪)區域\(z_{view}\)方向限定邊界,該區域稱為正交觀察體(orthographic view volume),這2個*面稱為*-遠裁剪*面(near-far clipping plane)或前-後裁剪*面(front-back clipping plane)。正交觀察體外的場景物件會被排除,不會顯示。觀察方向沿\(-z_{view}\)軸,有\(z_{far} < z_{near}\)
由遠、*裁剪*面形成的正交投影觀察體:
正投影的規範化變換
觀察座標系下,任一點\((x,y,z)\)到觀察*面的正交投影位置\((x,y)\)。觀察體內的物件,經規範化變換到規範化立方體,直接對映到規範化觀察體(normalized view volume/canonical view volume)。
規範化觀察體有兩種:
1)單位立方體:限制x、y、z範圍為0~1;
2)對稱立方體:限制x、y、z範圍為-1~1。
因為螢幕座標系常用左手系,所以規範化觀察體也用左手系。觀察方向正距離,代表距離螢幕(觀察*面)的距離。
左手螢幕座標系:
- 規範化變換
設**面、遠*面:\(z=z_{near},z=z_{far}, z_{far}<z_{near}<0\);規範化變換對映:\((xw_{min},yw_{min},z_{near})\to(-1,-1,-1)\),\((xw_{max},yw_{max},z_{far})\to(1,1,1)\)。
正交投影的規範化變換示意圖:
正交投影規範化變換有兩種推導方法:
方法一:分解法,將變換分解為三步:
1)*移:將觀察體中心*移到規範化座標系原點;
2)反射:以z軸為反射軸,將觀察體進行反射;
2)縮放:將x、y、z座標放縮到-1~1範圍.
*移矩陣:
∵\(z_{norm}\)軸與\(z_{view}\)軸反向
∴反射矩陣(參見計算機圖形:特殊幾何變換):
放縮矩陣:
複合變換矩陣:
方法二:座標變換法
以z軸為例:
變換遵循原則:z座標在變換前後,到起點的距離與z軸跨度的比例保持不變。即:
其中,*、遠*面為:\(z=z_{near},z=z_{far},z_{far}<z_{near}<0\)
同理,
根據座標變換,可以構造出正交投影變換矩陣\(M_{ortho,norm}\)(即上面式(7)),以滿足:
注意:有的文獻中,z軸變換會有差異,這是因為*、遠*面設定不同. 例如,令*、遠*面\(z=-z_{near},z=-z_{far},z_{far}>z_{near}>0\)
此時,
斜投影
當*行投影的投影線與觀察*面不*行時,該對映稱為斜投影(oblique parallel projection)。
*行投影={正交投影, 斜投影}
斜*行投影
如下圖,場景中一點\(P(x,y,z)\)在觀察*面(\(z=z_{vp}\))正投影點\(P_1(x,y,z_{vp})\),斜投影點\(P_2(x_p,y_p,z_{vp})\),\(|P_1P_2|=L\)。
斜*行投影用2個角度描述:
1)α,斜*行投影線與\(P_1P_2\)的夾角;
2)φ,\(P_1P_2\)與\(x_{view}\)軸的夾角;
其中,α∈[0,π/2),φ∈[0,2π)
斜投影座標:
\(\vartriangle PP_1P_2\)中,求L:
當\(z_{vp}-z=1\)時,\(L=\cot α\)
有,
α=π/2時,可得正投影。
- 斜*行投影向量
斜投影線的方向,稱為斜*行向量(parallel-projection vector),用\(V_p\)表示。觀察座標系下,\(V_p=(V_{px},V_{py},V_{pz}), \tan φ={V_{py}\over V_{px}}\),
∵\(V_p//\overrightarrow{P_1P_2}\)
∴\(V_p,\overrightarrow{P_1P_2}\)在\(x_{view},y_{view},z_{view}\)軸分量比例相同(證明見下文),即
於是,斜*行投影可用正交投影向量表示成:
推論:三維空間下,*行向量\(\vec V_1(x_1,y_1,z_1),\vec V_2(x_2,y_2,z_2)\)的xyz座標分量比例相同,即
\[{x_1\over y_1}={x_2\over y_2},{x_1\over z_1}={x_2\over z_2}, {y_1\over z_1}={y_2\over z_2} \]
證明:
假設\(\vec V_1=(x_1,y_1,z_1)//\vec V_2=(x_2,y_2,z_2)\),那麼,
存在λ∈R且λ≠0,使得
即得證。
斜等測、斜二測*行投影
φ常用π/3(60°)、π/4(45°),顯示物件前、側、頂檢視的組合(或前、側、底)。
α常用值:
1)α=45°(tan α=1),獲得檢視稱為斜等測(cavalier)投影圖,垂直於投影*面的線條投影后長度不變。
2)α≈63.4°(tan α=2),獲得檢視稱為斜二測(cabinet)投影圖,垂直於投影*面的線條投影后長度為原來一半。真實感較1)更好。
斜*行投影變換
由式(10),可得斜*行投影變換矩陣:
透視投影
將物件沿會聚到投影參考點(projection reference point)或投影中心(center of projection)的路徑投影到觀察*面來逼*幾何光學效果,稱為透視投影。
*行投影:保持物件相對比例;
透視投影:模仿人眼或照相機,具有*大遠小的真實感。
透視投影示意圖:
投影參考點與觀察原點
-
投影參考點是透視投影才有的概念;觀察原點是基於觀察座標系的概念,所有投影都有。
-
有的圖形軟體包將投影參考點設在觀察原點,即視點;有的將投影參考點作為另一觀察引數來選擇。i.e. 投影參考點可視作觀察原點,也可不同,取決於具體環境,參見下文“特殊透視投影”部分。
座標變換
場景中任一點\(P(x,y,z)\)到投影參考點\(P_{0}(x_{prp},y_{prp},z_{prp})\)的投影示意圖:
投影線與觀察*面交點\(P'(x_p,y_p,z_{vp})\)。
投影線上任一點\((x',y',z')\)引數方程(證明見下面推論):
u=0時,代表點P(x,y,z);
u=1時,代表投影參考點\(P_0(x_{prp},y_{prp},z_{prp})\)。
寫成點形式:
推論:兩點\(S_1(x_1,y_1,z_1)、S_2(x_2,y_2,z_2)\)確定直線段L,L上任一點\(S(x,y,z)\)座標方程:
\[\begin{cases} x&=ux_1+(1-u)x_2\\ y&=uy_1+(1-u)y_2 & u\in [0,1]\\ z&=uz_1+(1-u)z_2 \end{cases} \]
證明:
∵S位於直線L
∴\(S_1S//S_2S\)
∴存在非0實數λ,使得\(x-x_1=λ(x-x_2)\)
∴\(x={1\over 1-λ}x_1-{λ\over 1-λ}x_2\)
令\(u={1\over 1-λ}\),有\(x=ux_1+(1-u)x_2\)
∵x線上段\(S_1S_2\)上,不妨設\(x_1\le x_2\)
∴\(x_1\le x\le x_2\)
∴\(x_1\le ux_1+(1-u)x_2\le x_2\)
∴\(0\le u\le 1\)
同理可證,y、z座標也成立。故得證。
證明也可參見:數學基礎:三角形重心座標插值公式的證明
- 如何求投影變換公式?
要求投影變換公式,就需要求出P在觀察*面\(z'=z_{vp}\)上的投影點\(P'\)。
如上圖,根據三角形相似性,可求出:
於是
特殊透視投影
限制投影參考點或觀察*面。
1)投影參考點限制在\(z_{view}\)軸,即\(x_{prp}=y_{prp}=0\)
2)將投影參考點固定在原點,即\((x_{prp},y_{prp},z_{prp})=(0,0,0)\)
3)觀察*面是uv*面(uvn座標系),對投影參考點位置不限制,即\(z_{vp}=0\)
tips:uvn座標系下,\(u,v,n\)分別代表\(x_{view},y_{view},z_{view}\)。參見uvn觀察座標系。
4)觀察*面是uv*面,投影參考點在\(z_{view}\)軸,即\(z_{vp}=0,x_{prp}=y_{prp}=0\)
注意:投影參考點不能位於觀察*面\(z_{prp}\neq z_{vp}\),否則所有物件投影到觀察*面上一點。
滅點
當一個場景使用透視投影到觀察*面上時,*行於觀察*面的線條投影后仍然*行。但任何與觀察*面不*行的*行線組投影后,會成為一組會聚線條。一組投影*行線會聚的點,稱為滅點(vanishing point)。每組*行線都有自己的滅點。
主滅點(principal vanishing point):物件上*行於一個主軸的一組*行線的滅點。座標軸有3個,所以主滅點最多有3個。
透過投影*面的方向,可以控制主滅點的數量(1,2或3),對應透視投影分為一點、兩點或三點投影。
下圖是一個立方體的一點、兩點透視投影:
滅點與投影參考點
不同點:
- 是否能修改
投影參考點模擬人眼或攝像機,一旦選定,不能隨意修改;滅點會隨著物件的幾何變換而改變位置。
- 針對物件
滅點針對物件的一組*行線,可能有0個或多個;投影參考點針對所有透視投影,只有1個點。i.e. 透視投影一定存在投影參考點,而*行於觀察*面的線組不存在滅點。
透視投影觀察體
在觀察*面上指定一個矩形裁剪視窗,可得到透視投影觀察體(perspective projection view volumes),稱為視覺稜錐體(pyramid of vision)。稜錐體外的所有物件,都會被裁剪子程式消除。
視覺稜錐體:
注: 投影中心也是投影參考點。
新增垂直於\(z_{view}\)的遠、**面,可得到稜臺觀察體(frustum view volumes)。通常,遠、**面位於投影參考點同側(簡化版人眼/相機觀察模型),且遠*面距投影參考點更遠。
稜臺觀察體:
注:有些應用/模型為計算方便,將*裁剪*面設為與觀察*面重合.
透視投影變換矩陣
式(14)給出透視投影變換的一般形式,但不能直接得到變換矩陣,因為x、y係數含z(非常數)。可將其轉化成別的引數形式,然後再用三維齊次座標表示:
其中,任一點\(P(x,y,z)\),P的投影點\(P'(x_p,y_p,z_p)\),投影參考點\(P_0(x_{prp},y_{prp},z_{prp})\),觀察*面\(z=z_{vp}\)。
齊次引數:
\(x_h,y_h\):
用齊次座標的矩陣變換表示透視變換:
其中,\(P_h=(x_h,y_h,z_h,h)^T,P=(x,y,z,1)^T\)
可得一種可能的透視投影變換矩陣:
其中,引數\(s_z,t_z\)是z座標投影值規範化過程中的比例和*移因子,值依賴於稜臺觀察體範圍和規範化範圍。如果不放縮、*移,則預設值分別為1, 0。
特例:如果將投影參考點限制在觀察原點,且不做規範化和*移即\(s_z=1,t_z=0\),則\((x_{prp},y_{prp},z_{prp})=(0,0,0)\). 那麼,\(h=-z\)
對稱透視投影椎體
兩種描述方法:
1. 使用中心線
從投影參考點到裁剪視窗中心並穿過觀察體的線條,是透視投影稜臺的中心線。如下圖,如果中心線⊥投影*面,則觀察體為對稱稜臺(symmetric frustum)(相對於中心線)。
觀察座標系下,觀察*面\(z=z_{vp}\),投影參考點\(P_{prp}(x_{prp},y_{prp},z_{prp})\),則中心線與觀察*面交於\((x_{prp},y_{prp},z_{vp})\)。裁剪視窗寬、高分別為width、height,則裁剪視窗邊界:
注意:xw/yw的w指clipping window.
因此,對於對稱透視投影錐體,可用裁剪視窗寬、高代替視窗座標。
2. 使用視場角、裁剪視窗寬高比
視場角(field-of-view angle):稜臺的上裁剪*面與下裁剪*面的夾角。對稱稜臺*似於照相機鏡頭捕獲的場景視錐,可用於度量鏡頭的尺寸。
視場角與裁剪視窗高度關係:
於是,裁剪視窗高度:
再利用裁剪視窗寬高比aspect,就能得到寬度:\(width=aspect\cdot height\)
對稱稜臺觀察體經透視投影變換後,變成矩形*行管道觀察體,變換後的點的範圍限制在*行管道觀察體內:
斜透視投影稜臺
如果透視投影觀察體的中心線不垂直於觀察*面,則得到一個斜稜臺(oblique frustum)。
斜透視投影 = 錯切 + 透視變換
斜稜臺頂檢視:
斜稜臺投影觀察體,可透過相對於z軸的x方向、y方向錯切(參見三維錯切)變換成對稱稜臺。
為計算方便,將投影參考點設為觀察原點,即\((x_{prp},y_{prp},z_{prp})=(0,0,0)\). 可設錯切矩陣:
如果觀察*面 = *裁剪*面(即\(z_{vp}=z_{near}\)),則透視投影矩陣可進一步簡化。
∵錯切將裁剪視窗\((xw_{min},xw_{max},z_{near})\)中心移到觀察*面原點\((0,0,z_{near})\)處
∴錯切引數\(sh_{zx},sh_{zy}\)滿足:
∴有
- 簡化(對稱)透視投影矩陣
當投影參考點位於觀察原點,且*裁剪*面與觀察*面重合(OpenGL預設)時,則透視投影變換矩陣(22)可簡化為:
其中,z座標縮放和*移引數\(s_z, t_z\)由規範化確定。\(h=z_{prp}-z=-z\)
- 簡化斜透視投影矩陣
將簡化後的透視矩陣(27)和錯切矩陣(24)合併,可得到將場景中座標轉換為齊次正交座標系的斜透視投影矩陣。該變換中,投影參考點是觀察原點,*裁剪*面是觀察*面:
如果裁剪視窗關於觀察原點對稱,即\(xw_{max}=-xw_{min},yw_{max}=-yw_{min}\),則稜臺觀察體是對稱的,(28)可簡化為(27)(無需錯切,因為投影參考點位於觀察原點)。
透視投影的規範化變換
透視投影最後一步:稜臺觀察體(矩形*行管道,座標符合右手系)\(\xrightarrow{規範化}\)規範化觀察體(對稱立方體,座標符合左手系)。
透視投影規範化 = *行管道觀察體的正交投影
規範化示意圖(*裁剪*面作為觀察*面):
規範化變換中,矩形*行管道中心線\(z_{view}\),在x、y方向不再需要*移,只需要相對於原點的x、y縮放。xy規範化縮放矩陣:
將(28)(29)合併,生成透視投影變換的規範化矩陣:
(30)對應的規範化變換:
∴\(P(x,y,z)\)的投影座標\(P'(x_p,y_p,z_p)\):
其中,\(h=-z\)
如何確定引數\(s_x,s_y,s_z,t_z\)?
座標對映:\((xw_{min},yw_{min},z_{near})\xrightarrow{}(-1,-1,-1), (xw_{max},yw_{max},z_{far})\xrightarrow{}(1,1,1)\).
\(s_x,s_y\)分別將長度\(xw_{max}-xw_{min},yw_{max}-yw_{min}\)放縮為新長度2,2
∴
\(s_z,t_z\)將輸入座標\(z_{near},z_{far}\)分別轉換為\(-1,1\)
∴需滿足
∴有
∴代入(30)可得
這就是透視投影(包括規範化)矩陣.
注意:該投影矩陣對應模型與OpenGL約定一致,包括
1)觀察座標系為右手系統,規範化座標系為左手系統;
2)投影參考點位於觀察原點,觀察*面位於*裁剪*面;
3)遠、*裁剪*面關係:\(z_{far}<z_{near}<0\)(包含符號).