iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 25
0

前言

球範圍選擇,指的是以滑鼠點選的位置為中心點,一定半徑內的所有網格點資訊,這種方法可以用來模擬圓形的筆刷,接觸到三維空間中的物體表面。

球範圍選擇

首先改寫 EditormouseDown 函數,先複製先前的找最接近點的功能,並且定義想找尋的球半徑。

var radius = 1.5;

var intersected = self.viewer.intersects[0];
if (intersected.object.skip) return;
var topology = intersected.object.topology;

var vertices = self.getVertices();
var nearest = self.getNearest(vertices, intersected.point);

接著在 Editor 建立一個 circleSelect 函數用來求取範圍內選擇的點,此函數包含三個引數 目標點搜尋半徑點的清單,並且在內部先宣告必要的基本參數,以及在 selectedIDs 中放入目標點。

Editor.prototype.circleSelect = function (point, radius, selectedIDs) {
    var self = this;
    var intersected = self.viewer.intersects[0];
    var topology = intersected.object.topology;
    if(!selectedIDs) selectedIDs = [];
    selectedIDs.push(point.ID);
    
    // Do Something
    
    return selectedIDs;
};

然後建立兩個迴圈,第一層迴圈內利用的目標頂點的邊拓樸關係找到鄰近的的點群,第二層迴圈則查詢這些點的是否不在 點的清單 內。

var i = 0;
var j = 0;
var edgeIDs = point.edgeIDs;
for(i=0;i<edgeIDs.length;i++) {
    var edgeID = edgeIDs[i];
    var edge = topology.edge[edgeID];
    var vertexIDs = edge.vertexIDs;
    for(j=0;j<vertexIDs.length;j++) {
        var vertexID = vertexIDs[j];
        if(selectedIDs.indexOf(vertexID) === -1) {
            
            // Do Something
            
        }
    }
}

最後計算頂點距離是否小於半徑,是的話就從該點繼續進行反覆查找的動作直到結束。

var vector = topology.vertex[vertexID];
var distance = intersected.point.distanceTo(vector.vector3);
if(distance < radius) {
    self.circleSelect(vector, radius, selectedIDs);
}

回到 mouseDown 函數,呼叫 circleSelect 函數取得球範圍內的點,並且畫幾顆球做顯示,效果如下圖。

var selectedIDs = self.circleSelect(nearest, radius);

var i = 0;
for(i=0;i<selectedIDs.length;i++) {
    var selectedID = selectedIDs[i];
    var selected = topology.vertex[selectedID];

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

https://lh3.googleusercontent.com/SXMG96RublE09Zt8bno4JgfYSNe7A_dDTz1PD1XomUOmU4lg-N4Iyk_JocsuAjD1TmcHPzZd5yDLZiBXdg=s0-tmp.gif
在球模型 SphereD10Binary.STL 進行球範圍選擇頂點

範例模型下載位置

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

線上範例

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

範例原始碼

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

後記

本次先預備好球範圍選擇功能,會應用到後續的功能中,其採用了較簡易的計算方式相信大家都能吸收良好。另外除了使用邊拓樸以外也可以使用面拓樸來搜尋,若需要更準確且效率高的方法,必須另外建立網格碰撞及模型搜尋的樹狀結構關係,而本文僅就基礎說明就不再深入了。


上一篇
Day 24 : 封閉網格與非封閉網格
下一篇
Day 26 : 三角網格平滑變形
系列文
在Three.js探索CAD的奧秘30

尚未有邦友留言

立即登入留言