隱式曲線曲面與梯度、三角形與重心坐標


目前的圖形學研究都繞不開幾何圖元,其中個人學習中比較難以理解的是隱式曲線和曲面,與之對應的偏導、梯度等幾何信息,以及與模型表示最為密切的三角形,因此寫下此篇總結,供復習回顧。

隱式曲線曲面

2D曲線最符合直覺的定義可以是:在一張紙上一筆所畫出的一條線,而這條線可以表示為一系列點的集合。對於一般情形,用一個方程可以描述任意二維實曲線:

\[f(x,y)=0 \]

由於這條曲線是在方程中隱式定義的,因此也稱為隱式曲線。

常見的隱式曲線有:

隱式直線:

\[Ax+By+C=0 \]

隱式二次曲線:

\[Ax^2+Bxy+Cy^2+Dx+Ey+F=0 \]

如隱式橢圓:

\[f(\textbf{p})={(x-x_c)^2\over a^2}+{(y-y_c)^2\over b^2}-1=0 \]

3D隱式曲面與2D隱式曲線類似,可用隱函數

\[f(x,y,z)=0 \]

定義3D隱式曲面,解集即為曲面上所有點的集合,我們可以通過隱函數判斷點是否在面上,但大多數時候我們無法顯化其表達式,即無法顯式構造位於面上的點。

為方便表示,記 \(\textbf{p}=(x,y,z)\) ,則

\[f(\textbf{p})=0 \]

常見的隱式曲面:

隱式平面:已知平面包含點 \(a\) ,且法向量為 \(\textbf{n}\) ,則平面方程為

\[(p-a)\cdot\textbf{n}=0 \]

3D隱式二次曲面如橢球面:

\[f(\textbf{p})={(x-x_c)^2\over a^2}+{(y-y_c)^2\over b^2}+{(z-z_c)^2\over c^2}-1=0 \]

由方程組定義的3D隱式曲線 (曲面的交線):

\[\left\{ \begin{aligned} f(\textbf{p})&=0\\ g(\textbf{p})&=0 \end{aligned} \right. \]

梯度

梯度是一個重要的度量,在幾何領域,除了用梯度描述變化之外,梯度還經常用於求法線等操作。

對於一維的情況,我們可以用極限定義導數為切線斜率。而一個二維函數並不能做類似一維情況下的極限運算,因為對於給定的 \(x\)\(f\) 的變化方式多種多樣,而如果我們把 \(y\) 視為常數,則可以定義一個類似導數概念,這就是偏導數 (Partial Derivatives):

\[{\partial f\over\partial x}=\lim_{\Delta x\rightarrow0}{f(x+\Delta x,y)-f(x,y)\over\Delta x} \]

如果把函數值當成第三維,那么可以表示為一個高度場,此時 \((x,y,f(x,y))\) 是一個三維表面。在 \(xOy\) 平面上任意指定一個方向,我們都可以定義一個該表面的導數,該導數值是沿這樣一個方向的導數,這個方向在 \(xOy\) 平面的投影為我們所指定的方向,這就是方向導數 (Directional Derivatives)。對應回二維的情況,這里實質上是對導數做了推廣。對 \(x\)求導,實際上是求沿 \(x\)​ 方向的函數變化率,既然是對方向求導,自然可以推廣到沿任意方向求導,也就是方向導數。 (但其實有細微區別,通常討論的可求導或偏導,指的是沿軸向雙向均可導且導數值均相同)

\(l\)​ 是 \(xOy\) 平面上以 \(P_0(x_0,y_0)\) 為始點的一條射線\(e_l=(\cos\alpha,\cos\beta)\) 是與 \(l\) 同方向的單位向量 (方向余弦表示),射線 \(l\)​ 的參數方程為

\[\left\{ \begin{aligned} x&=x_0+t\cos\alpha\\ y&=y_0+t\cos\beta \end{aligned} \right. \]

則方向導數可定義為

\[\left.{\partial f\over\partial l}\right|_{(x_0,y_0)}=\lim_{t\rightarrow0^+}{f(x_0+t\cos\alpha,y_0+t\cos\beta)-f(x_0,y_0)\over t} \]

在可微條件下,有

\[\begin{aligned} &f(x_0+\Delta x,y_0+\Delta y)-f(x_0,y_0)\\ =&f_x(x_0,y_0)\Delta x+f_y(x_0,y_0)\Delta y+o\left(\sqrt{(\Delta x)^2+(\Delta y)^2} \right)\\ =&f_x(x_0,y_0)\cos\alpha+f_y(x_0,y_0)\cos\beta+o\left(t\right) \end{aligned} \]

\[\left.{\partial f\over\partial l}\right|_{(x_0,y_0)}=f_x(x_0,y_0)\cos\alpha+f_y(x_0,y_0)\cos\beta \]

基於方向導數可以定義梯度。梯度 (Gradients)是一個向量,它指示的就是這樣一個方向:從當前點出發在曲線上運動時,沿該方向運動,高度爬升得最快,變化率最快,或者說,方向導數最大。可以定義梯度

\[\mathrm{grad}f(x_0,y_0)=\nabla f(x_0,y_0)=f_x'\ \textbf{i}+f_y'\ \textbf{j} \]

其中, \(\nabla={\partial\over\partial x}\ \textbf{i}+{\partial\over\partial y}\ \textbf{j}\) 為向量微分算子Nabla

根據方向導數的定義可知,

\[\left.{\partial f\over\partial l}\right|_{(x_0,y_0)}=(f_x',f_y')\cdot e_l=\left|\mathrm{grad}f(x_0,y_0)\right|\cos\theta \]

由於射線的方向向量是單位向量,因此最終方向導數可以表示為上式,其中, \(\theta\)​ 是射線方向向量與梯度方向的夾角。當射線方向與梯度方向相同時,方向導數取得最大值,且最大值為梯度的模。

若取平面 \(z=c\) 截該高度場,可得一等值線

\[\left\{ \begin{aligned} z&=f(x,y)\\ z&=c \end{aligned} \right. \]

對應隱式曲線 \(f(x,y)=c\)​ ,改寫為參數形式

\[\left\{ \begin{aligned} x&=x\\ y&=y(x) \end{aligned} \right. \]

隱函數兩邊對 \(x\) 求偏導可得,

\[f_x(x,y)=f_x(x,y(x))=f_x'+f_y'\ y_x'=(f_x',f_y')\cdot(1,y_x')=0 \]

對比定義可知,上式點積為0即表明梯度與切向量垂直。

特別地,令 \(c=0\)​ 即原曲線,也即,曲線法向量可用梯度方法求,且有

\[\nabla f(x,y)=({\partial f\over\partial x},{\partial f\over\partial y}) \]

類似地,3D隱式曲面的法線為

\[\textbf{n}=\nabla f(\textbf{p})=\left({\partial f\over\partial x},{\partial f\over\partial y},{\partial f\over\partial z} \right) \]

同樣地,梯度法所求的法線方向指向的是 \(f(\textbf{p})>0\) 的區域。

參數曲線曲面

有時使用參數方式定義的隱式曲線曲面會更便於計算,同時,參數形式給出了一種構造點的方法。

2D參數曲線通常定義為

\[\left\{ \begin{aligned} x&=g(t) \\ y&=h(t) \end{aligned} \right. \]

如圓

\[\left\{ \begin{aligned} x&=R\cos\theta\\ y&=R\sin\theta \end{aligned} \right. \]

3D參數曲線通常定義為

\[\left\{ \begin{aligned} x&=f(t)\\ y&=g(t)\\ z&=h(t) \end{aligned} \right. \]

如螺線

\[\left\{ \begin{aligned} x&=\cos t\\ y&=\sin t\\ z&= t \end{aligned} \right. \]

3D參數曲面通常定義為

\[\left\{ \begin{aligned} x&=f(u,v)\\ y&=g(u,v)\\ z&=h(u,v) \end{aligned} \right. \]

如球面

\[\left\{ \begin{aligned} x&=R\cos\phi\sin\theta\\ y&=R\sin\phi\sin\theta\\ z&=R\cos\theta \end{aligned} \right. \]

三角形與重心坐標

三角形是最基本的圖元。由於通常我們只擁有給定的三角形的頂點處的信息,在圖形計算中,需要插值以生成可平滑覆蓋的像素信息。而三角插值依賴最多的是重心坐標。

hedK9x.png

重心坐標 (Barycentric Coordinates)是一個非標准正交的坐標系,其以三角形的一個頂點為坐標原點,以過該點的兩邊為坐標軸。在三角形所在平面內的任意一點 \(\textbf{p}\) 均可表示為

\[\textbf{p}=\textbf{a}+\beta(\textbf{b}-\textbf{a})+\gamma(\textbf{c}-\textbf{a}) \]

\(\alpha=1-\beta-\gamma\) ,整理得一個對稱表達的形式

\[\textbf{p}=\alpha\textbf{a}+\beta\textbf{b}+\gamma\textbf{c} \]

\((\alpha,\beta,\gamma)\) 稱為點 \(\textbf{p}\) 的重心坐標。

利用重心坐標可快速判斷點與三角形的位置關系:

  • 若坐標分量均位於 \((0,1)\) ,則點在三角形內
  • 若坐標分量恰有一個為0,且其余兩個均位於 \((0,1)\) ,則點在三角形上
  • 若坐標分量有兩個為0,則點與三角形頂點重合
  • 除此之外,點在三角形外

由於重心坐標的表達式已給出,則可以得到一個關於坐標的方程組,直接求解即可得到重心坐標。但這種方法沒有將其幾何意義融入計算。

對於重心坐標的一個理解是:坐標的分量值對應該頂點到其對邊的有向比例距離 (Signed Scaled Distance)。

hedmNR.png

利用之前隱式曲線的知識,對於邊 \(ac\)​ ,設其對應隱函數為 \(f(x,y)=0\)​ (這里以二維情況討論,而其結論可以幾乎完全推廣到三維情況,只需添加一維坐標即可),而對於函數 \(d=kf(x,y)\)​ ,其表示的正是平面內的點到邊 \(ac\) 有向比例距離,對比重心坐標可知,我們只需要找到一個 \(k\) ,使得 \(kf(x_b,y_b)=1\)​ ,因此我們得以計算重心坐標

\[\beta={f_{ac}(x,y)\over f_{ac}(x_b,y_b)} \]

代入兩點坐標,以直線的一般式表示則有

\[\beta={(y_a-y_c)x+(x_c-x_a)y+x_ay_c-x_cy_a\over(y_a-y_c)x_b+(x_c-x_a)y_b+x_ay_c-x_cy_a} \]

同理可得 \(\gamma\) 的表達式,再由 \(\alpha=1-\beta-\gamma\) 即可計算重心坐標。

另一種理解重心坐標的方式是面積法。同樣考慮邊 \(ac\) ,以之為底的三角形,以同樣的 \(\beta\) 為高時,三角形的面積不變,且當 \(\beta=1\) 時,面積為整個三角形的面積,即

\[\beta={A_b\over A} \]

在允許面積帶有方向時,該方法也可以表示面內所有的點。又由叉積可得三角形法線和面積

\[\textbf{n}=(b-a)\times(c-a)\\ A={1\over2}||\textbf{n}|| \]

這個面積並非有向面積,所以並不能直接用於面積法求重心坐標。但可以觀察到,當三角形的三個頂點繞序不同時,其有向面積的符號也是不同的。因此我們定義

\[\textbf{n}_a=(c-b)\times(p-b) \]

對應由點p、b、c組成的三角形,若p、a均位於bc的一側,則叉積方向一致,反之則反。又因為所有點均在同一平面內,因此, \(\textbf{n}\)\(\textbf{n}_a\) 平行。那么,

\[\alpha={A_{signed,a}\over A_{signed}}={{1\over2}||\textbf{n}_{a}||\cdot signed(\textbf{n}_a)\over{1\over2}||\textbf{n}||\cdot signed(\textbf{n})}={||\textbf{n}||\ ||\textbf{n}_{a}||\cdot \left<\textbf{n},\textbf{n}_a\right>\over||\textbf{n}||\ ||\textbf{n}||\cdot \left<\textbf{n},\textbf{n}\right>} ={\textbf{n}\cdot\textbf{n}_a\over\textbf{n}\cdot\textbf{n}} \]

推廣到3D情況,此時我們假設涉及的點均為三維空間中的點,上述規則仍然成立。

參考

Fundamental of Computer Graphics 4th Edition, Chapter 2.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM