iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 26
1
Modern Web

在Three.js探索CAD的奧秘系列 第 26

Day 26 : 三角網格平滑變形

  • 分享至 

  • xImage
  •  

前言

平滑階梯函數(Smoothstep),屬於S型函數(Sigmoid function),是一種常用的繪圖函數,在繪圖領域通常將最小極限設為0,最大極限設為1,其函數及圖形如下:

https://ithelp.ithome.com.tw/upload/images/20180114/20107175DSniuOJ3Js.png
平滑階梯函數的數學模型: S(x) \begin{cases} 0 & x\leq 0 \ 3x^{2}-2x^{3} & x\geq 0, x\leq 1 \ 1 & x\geq 1 \end{cases}

https://ithelp.ithome.com.tw/upload/images/20180114/20107175oNE24W8e7J.png
平滑函數的曲線圖形: y=3x^2-2x^3, x is from 0 to 1

平滑變形

接續前回我們找尋到了球範圍內的所有點資訊,我們將透過改變這些點群來獲得一個平滑的曲面,首先在 Editor 模組建立一個平滑階梯函數 smoothstep

Editor.prototype.smoothstep = function (x) {
    // 3x^2 - 2x^3
    if (x <= 0) {
        return 0;
    } else if (x > 0 && x < 1) {
        return 3 * (x * x) - 2 * (x * x * x);
    } else if (x >= 1) {
        return 1;
    }
};

回到 mouseDown 將先前的繪製點功能部分刪除,改為計算各點到球心的距離並且與半徑進行正規化,而為了讓越接近球心的數值越大,因此需要用1減去正規化的數值以獲得反轉的正規化數值。

var distance = intersected.point.distanceTo(selected.vector3);
var normalize = 1 - (distance / radius); // 0 ~ 1

將正規化數值 normalize 代入今天的主角 smoothstep 函數獲得一個解。

var solution = self.smoothstep(normalize);

根據之前學到的點頂位移的計算方式,將法向量 乘上 平滑函數的解 與 強度值後,加到要改變的網格點以改變位置。

var intensity = 1.5;
//...
var newVector = normal.clone().multiplyScalar(solution).multiplyScalar(intensity);
selected.vector3.add(newVector);
geometry.vertices[selected.ID].copy(selected.vector3);

接著使用先前學到的方法修正所有面的法向量,以及拓樸的中心點位置資訊。

for (j = 0; j < selected.faceIDs.length; j++) {
    var id = selected.faceIDs[j];
    var cb = new THREE.Vector3();
    var ab = new THREE.Vector3();
    var vA = topology.vertex[topology.face[id].vertexIDs[0]].vector3;
    var vB = topology.vertex[topology.face[id].vertexIDs[1]].vector3;
    var vC = topology.vertex[topology.face[id].vertexIDs[2]].vector3;
    cb.subVectors(vC, vB);
    ab.subVectors(vA, vB);
    cb.cross(ab);
    geometry.faces[id].normal.copy(cb.normalize());
}
//修正中心點位置
topology.computeCenter(selected.ID);

最後不要忘記更新所有幾何資訊,完成的效果如下圖。

geometry.normalsNeedUpdate = true;
geometry.verticesNeedUpdate = true;
geometry.elementsNeedUpdate = true;

https://i.imgur.com/y3mjx3I.gif
網格模型平滑變形效果

範例模型下載位置

https://github.com/QQBoxy/threecad/tree/master/models

線上範例

https://qqboxy.github.io/threecad/public/example21.html

範例原始碼

https://github.com/QQBoxy/threecad/blob/master/client/example21/Editor.js

後記

本次展示了平滑曲面變形的效果,到這個階段已經能看到些許專業繪圖軟體的影子,不過卻是在Web-based搭建的應用程式,大家有沒有覺得建立一套3D的CAD軟體其實並沒有想像中的那樣困難,繼續跟著筆者探索CAD的奧秘吧!


上一篇
Day 25 : 球範圍選擇
下一篇
Day 27 : 三角網格邊翻轉
系列文
在Three.js探索CAD的奧秘30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言