網格頂點的選取,非常廣泛的應用在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://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軟體重要的基礎,在變形工具中找到網格點是很常用的,希望大家都有跟上學習的腳步喔。