iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 19
0
Modern Web

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

Day 19 : 點選網格頂點

前言

網格頂點的選取,非常廣泛的應用在CAD軟體中,先前我們學到如何選取整個網格,今天則回過頭來學習怎麼選取網格的頂點。

其實很難點選

事實上滑鼠是很難準確的點擊到我們想要的頂點,因此要完成這個功能我們只要找到最鄰近的點就可以了。其原理相當簡單只要從點擊到的三角網格,尋找滑鼠點擊到的位置中最接近的那個三角網格頂點就行了,如此一來就能模擬出好像真的點到了頂點的效果。

搜尋鄰近點

首先我們整理先前所撰寫的找尋face中的三個vertex的方法,建立成 getVertices 函數供使用,

Editor.prototype.getVertices = function () {
    var self = this;
    var vertices = [];
    var intersected = self.viewer.intersects[0];
    var ids = [
        intersected.face.a,
        intersected.face.b,
        intersected.face.c
    ];
    var i = 0;
    for(i=0;i<ids.length;i++) {
        vertices.push(intersected.object.geometry.vertices[ids[i]]);
    }
    return vertices;
};

接著撰寫搜尋最近點的函數 getNearest 供搜尋某個 point 與 vertex 陣列哪一點最近。

Editor.prototype.getNearest = function (vertices, point) {
    var i = 0;
    var temp = Infinity;
    var distance = 0;
    var min = {};
    for (i = 0; i < vertices.length;i++) {
        distance = vertices[i].distanceTo(point);
        if (distance < temp) {
            temp = distance;
            min = vertices[i];
        }
    }
    return min;
};

然後在 mouseDown 函數中加入兩個函數的呼叫,找到最鄰近的點。

var vertices = self.getVertices();
var nearest = self.getNearest(vertices, self.viewer.intersects[0].point);

最後簡單的畫個球來表示效果,結果如下圖。

var geometry = new THREE.SphereBufferGeometry(0.2, 16, 16);
var material = new THREE.MeshPhongMaterial({
    color: 0x00ff00
});
var mesh = new THREE.Mesh(geometry, material);
mesh.skip = true;
mesh.position.copy(nearest);
self.viewer.scene.add(mesh);
self.viewer.meshs.push(mesh);

https://i.imgur.com/Wpjggw9.gif
點選網格頂點範例

範例模型下載位置

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

線上範例

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

範例原始碼

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

後記

本次的範例非常簡單,但也是建構CAD軟體重要的基礎,在變形工具中找到網格點是很常用的,希望大家都有跟上學習的腳步喔。


上一篇
Day 18 : 模型所見即得的設計
下一篇
Day 20 : 網格頂點的平均法向量
系列文
在Three.js探索CAD的奧秘30

尚未有邦友留言

立即登入留言