本文主要的參考文獻爲:
1. 遊戲編程中的數學——調和函數和中值座標
2. Hormann K, Floater M S. Mean value coordinates for arbitrary planar polygons[J]. Acm Transactions on Graphics, 2006, 25(4):1424-1441.
3. Floater M S. Mean value coordinates[J]. Computer Aided Geometric Design, 2003, 20(1):19-27.
一般來說,我們不通過一個模型含有的網格(通常爲三角形網格或四邊形網格)以及頂點去理解它,而是在其網格上建立一個函數,這個函數擁有特定的性質,有助於解決我們面臨的難題。那麼這次介紹一個在網格上建立函數的方法——中值座標。中值座標是90年代後期產生的,其背後的數學原理卻得追述到18、19世紀了,然而直到今天它依然沒有受到遊戲開發界足夠的重視……本文重點是談談中值座標的構造與應用。
中值座標的“前菜”
由
這些歸一化後的重心座標在網格上是連續的,並且具有
這就是爲什麼它們通常用於對一個三角形區域進行線性插值,並且在計算機圖形學中具有廣泛的應用(例如
在許多實際應用中,將重心座標推廣到具有任意
再將其歸一化得
這樣平面上的任一點
中值座標的構造
令
如圖所示爲一些簡單多邊形的小栗子:
由上圖可以看出,簡單多邊形可以爲凹多邊形,也支持嵌套操作,並不侷限於單個凸多邊形。
對於
這是通常的歐氏距離,並用
它們分別表示
易知
通常,這些座標還需要進行歸一化,即需要除以
現在讓我們來考慮一下
其中權重函數
欲驗證上式,我們首先得解釋一下當
由上圖可以看出,
現在的關鍵步驟是對於齊次重心座標的歸一化,必須保證
事實上,由
當
然而,在一個非凸多邊形中,
爲了解決上述問題,通常採用的解決方案是令權重函數
針對上述問題,
其中
現在,我們就來介紹一種最常用的重心座標,它就是我們今天這篇文章的主角——中值座標,其權重函數是醬紫定義的:
可能看到這裏就有人感到不解了,這貨長得不就跟
事實上,這個證明是比較複雜的,需要兩個引理才能證明,篇幅較長,因此這裏不再贅述。有興趣的同學可以看看第2篇參考文獻,文中的定理4.3便給出了答案。
繼續走下去,將
再將
上式是
至此,離整個中值座標的構造便僅差一步了!!!✿✿ヽ(°▽°)ノ✿
中值座標的性質
對於任一簡單多邊形的集合
中值座標具有如下優美的性質(證明都可以參見第2篇參考文獻):
- 仿射精度:對於任一仿射函數
φ:R2→Rd 都有∑i=1nλiφ(vi)=φ ; Lagrange 性:λi(vj)=δi,j ;- 光滑性:當
v≠vj 時,λi∈C∞ ;而當v=vj 時,λi∈C0 ; - 正則性:
∑i=1nλi≡1 ; - 相似不變性:如果
φ:R2→R2 是具有相似性的(此處具有相似性的變換定義爲該變換是一個平移變換,旋轉變換,反射變換,等距縮放變換或者它們的組合),且Ψ^=φ(Ψ) ,則λi(v)=λ^i(φ(v)) ; - 線性無關性:如果
∑i=1nciλi(v)=0,v∈R2 ,則ci=0 ; - 如果我們令
Ψ^ 是由Ψ 在ej 邊上增加一點v^=(1−μ)vj+μvj+1 ,則λj=λ^j+λ,λj+1=λ^j+1+μλ^ ,且λi=λ^i,i≠j,j+1 ; - 線性性:
λi 在Ψ 的任一條邊ej 上是線性的; 非負性:
λi 在凸多邊形的內核上是正的,其中,平面上簡單多邊形的核是該多邊形內部的一個點集,該點集中任意一點與多邊形邊界上一點的連線都處於這個多邊形內部。譬如說,就是一個在一個房子裏面放一個攝像 頭,能將所有的地方監視到的放攝像頭的地點的集合即爲多邊形的核。(參考自博客半平面交,求解多邊形內核)至此,整個中值座標的構造算是大功告成了!!!✿✿ヽ(°▽°)ノ✿
中值座標的應用
中值座標最主要的應用便是在給定簡單多邊形
由於
事實上,接下來所討論的兩個應用本質上還是體現了一種插值思想。
圖像變形
中值座標的一個應用是圖像變形,因爲中值座標爲這個問題提供了一個特別簡單的解決方案,可簡要地說明如下。
給定一個矩形區域
許多時候,圖像變形函數可以用
它將每一個
gi(x) 滿足gi(v^i)=vi ,這是對於點v^i 的插值,i=1,2,⋯,n 。對於插值基函數gi 而言,一般使用線性或者二次多項式,多項式係數可以用插值點處的導數值去確定。λi:R2→R 是權函數,須滿足條件λi(v^i)=1,∑i=1nλi(v^i)=1 且λi(v^)⩾0,i=1,2,⋯,n 。
Shepard 提出了以下簡單的權函數:
λi(v^)=ωi(v^)∑i=1nωj(v^),
其中ωi(v^)=1ri ,ri 是v^ 與v^i 的距離。
IDW 是一種全局插值算法,即全部樣本點都會參與到與某一插值結點(實際運用當中又叫控制點)的運算當中去,所以它的計算複雜度起碼爲O(nN) ,其中n 是控制點的數量,N 是整個目標圖像的像素點數量。
我們不妨來看一下分別令I^=I∘f 與I^=I∘g 會產生什麼不同的神奇現象。(g=f−1 ,下面直接令gi(v^)=v^+vi−v^i )
若採用I^=I∘f ,容易發現生成的目標圖像中會出現許多空洞點(爲了突出空洞點,圖中用深紅色點表示空洞點),如下圖所示:
正向映射實驗效果圖對於上述問題,我們需要對空洞進行填補,我分別採用了均值濾波模板、中位數濾波模板與即時填充空洞進行處理:
均值濾波模板填補效果圖
填補後局部放大圖
容易看出,在對圖像進行空洞區域的填補以後,出現了一些疑似空洞的點,故仍需要進行改進。先來簡要分析一下原因~
由於存在取平均值的操作,故當一個像素點周圍存在不同顏色的像素點時,填補以後容易出現顏色差異較大的點,譬如黑色方塊和白色方塊相鄰邊界上的空洞點,填補以後就會變成灰色點。
找到原因以後便可以有針對性地進行改進,自己採用的解決方案是替換均值濾波模板改用中位數濾波模板,需要注意的是,對一個空洞點填補時並不考慮周圍的空洞點,即不應該將空洞點的像素用來求中位數;其次,若一個空洞點周圍的非空洞點像素點數量爲偶數時,其中位數是需要取平均的,此時容易出現類似使用均值濾波模板的填補錯誤,於是需要進行如下判斷,假設該空洞點周圍的非空洞點像素點數組爲
if surrounding_pixels[i] = = surrounding_pixels[i - 1],i=surrounding_pixels.size()/2
將surrounding_pixels[i]賦給空洞點;
else
爲了避免出現取均值的操作,依然將surrounding_pixels[i]賦給空洞點;
中位數濾波模板填補效果圖
在作了上述改進以後,發現仍存在一些問題,如:
改進填補後的局部放大圖
可以看出,一些方塊邊緣會出現“毛邊”現象,即方塊顏色會“滲入”相鄰的方塊。究其原因,發現在填補時空洞點周圍的空洞點太多,影響了其中位數的取值,因爲對空洞點進行中位數濾波時是要捨去周圍的空洞像素的,如下圖所示:
爲了解決上述現象,需要對空洞點進行即時填補,因爲在之前的程序當中,找到空洞點對其進行中位數濾波以後,出於當前填補結果若是錯誤會對後面的填補效果產生影響的考慮,並非直接進行填補,而是先把像素存儲起來,等到最後再進行填補。
而現在則需要對此做出改變,只要保證當前空洞點的填補結果是正確的就可以了。自己的做法如下所示:假設該空洞點周圍的非空洞點像素點數組爲
if surrounding_pixels[i] = = surrounding_pixels[i - 1],i=surrounding_pixels.size()/2
將surrounding_pixels[i]賦給空洞點;
else
先不進行操作,將這個點記錄下來,等對全部點進行中值濾波以後再對這個點進行中值濾波,此時因爲之前的空洞點已被填補,故它能獲得更多有效的像素點;
即時填補空洞效果圖
可以看出,在改進以後實驗結果有了一定的改善。那麼,我們再來看一下采用
逆向映射實驗效果圖
可以看出,實驗的效果十分理想。無論是在算法運行時間及算法實現難度上都遠勝之前的正向映射+空洞填補算法。當然對於圖像變形還有其它優秀的算法,比如徑向基函數算法(
紋理參數化
中值座標的另一個應用是紋理參數化,簡要地說明如下。
(圖片畫得並不是很標準哈,見諒(:3 」∠) )
首先需要進行局部參數化:將局部結構映射到平面上,映射過程滿足下列條件:
其中,
對於點
如此一來,我們便可以定義函數
其中,
然而,真正將上述方法用於紋理參數化的話會出現計算量太大的問題,因爲它需要對模型內每一個點進行計算。因此,在實際運用當中,如果模型是比較規則的或者有足夠多的頂點集,則可以棄用上述的中值座標,改用構造一個關於頂點變換的稀疏線性系統,亦可以求出形狀變化比較小的參數化結果。
原網格
參數化結果
總結
我們已經表明,中值座標將三角形重心座標的概念推廣到任意的簡單多邊形,甚至是這些簡單多邊形的集合。中值座標具有許多很漂亮的性質(如
我們注意到,中值座標在任意簡單多邊形的情況下並不是處處都是正的。另一方面,可能是恰恰由於這些性質,中值座標的插值性能才能如此棒,而且在實際應用中發揮着重要作用。(๑•̀ㅂ•́)و✧文中實驗的源碼會上傳到我的