As-rigid-as possible shape manipulation: 第二步算法的第一小步代碼
- 2019 年 10 月 8 日
- 筆記
根據上一篇文章,對於這一小步算法,我們令

令


最小化這個誤差和,對 w 求偏導,並使其偏導值為 0。

我們依然用Mathematica推導公式。

如上代碼,我們把公式寫成"手寫"公式一樣的形式。我們分別聲明了

和

以及

。
構造係數矩陣 F。

輸出 F 結果為


如果放大上面的公式,結果很完美,可視化效果特別好看。挑其中一個係數放大看。

但是這種可視化效果對於寫C++程序完全沒有用

。
重新改寫各個變量的聲明。

我們摒棄了可視化效果很好的「上下標」,全部用普通字符來表示。再看輸出係數矩陣 F 的代碼。

輸出其中一個係數看一下結果。

把輸出直接拷貝到文本編輯器。

除了Power函數不合適,其他都可以很完美的輸出到C++代碼中。
另外,係數矩陣 C 如下。

接下來我們看C++代碼。先直接看求取係數矩陣 F 和 C 的函數。

由上一篇文章。這一小步算法針對三角形做變形,每個三角形之間相互獨立,每個三角形單獨優化。所以根據第一步算法的代碼,我們需要修改Triangle結構體。

其中每個三角形做優化需要生成係數矩陣 F 和 C ,優化函數PreComputeScaleAdjustmentMatrixFC。另外,scale_factor_divisor 變量作為「放縮」變量。在上篇文章末尾說到。為了抵消"縮放"的效果,我們要計算一個比值

,然後對變形的三角形按照縮放比值來變換。這個 scale_factor_divisor 就是預計算的

。
另外,Mesh類也需要修改,需要添加一個函數給每個三角形做變形。

添加AdjustScaleToTriangle函數,輸入三角形序號,輸出三角形三個頂點的坐標,這裡只輸出 (x, y) 坐標值。

係數矩陣 F 和 C 在Mesh的Read函數(具體看Coding.net本項目的源碼)時就已經預計算過了。然後我們計算新的 v0f, v1f, v2f 這三個三角形頂點。最後幾行就是對三角形做「放縮」。
最後看一下這一小步的結果。綠色框三角形就是這一小步的結果。黑色框三角形是第一步算法的結果。

該文所有代碼都已開源,地址為:
https://coding.net/u/forestsen/p/ARAPShapeManipulation