人
我有直接的函数来识别THREE.Geometry()中的边。
var edges = [];
for(var i = 0, l = geometry.faces.length; i < l; i++) { findAdjacentFaces(i, edges, geometry); }
function findAdjacentFaces(face_, edges_, geometry_){
var adjacentFaces = [];
if(face_ >= 0 && face_ < geometry_.faces.length){
for(var i = 0, l = geometry_.faces.length; i < l; i++){
if(i != face_){
if(checkAdjacent(geometry_.faces[face_], geometry_.faces[i]) == true ){
adjacentFaces.push(i);
}
}
if(adjacentFaces.length > 2) { break; }
}
}
if(adjacentFaces.length == 2){
edges_.push(setEdge(face_, adjacentFaces[0], adjacentFaces[1], geometry_));
}
}
function checkAdjacent(faceA_, faceB_){
var values = [faceA_.a, faceA_.b, faceA_.c, faceB_.a, faceB_.b, faceB_.c].sort();
var counter = 0;
var duplicates = {};
values.forEach(function(x) { duplicates[x] = (duplicates[x] || 0) + 1; if(duplicates[x] > 1) { counter++; } });
if(counter == 2) { return true; } else { return false; }
}
function setEdge(faceA_, faceB_, faceC_, geometry_){
var vertices = [], peak, tmpA, tmpB;
var values = [ geometry_.faces[faceA_].a, geometry_.faces[faceA_].b, geometry_.faces[faceA_].c,
geometry_.faces[faceB_].a, geometry_.faces[faceB_].b, geometry_.faces[faceB_].c,
geometry_.faces[faceC_].a, geometry_.faces[faceC_].b, geometry_.faces[faceC_].c ].sort();
var sideA = [geometry_.faces[faceA_].a, geometry_.faces[faceA_].b, geometry_.faces[faceA_].c];
var sideB = [geometry_.faces[faceB_].a, geometry_.faces[faceB_].b, geometry_.faces[faceB_].c];
var sideC = [geometry_.faces[faceC_].a, geometry_.faces[faceC_].b, geometry_.faces[faceC_].c];
var counter = 0;
var duplicates = {};
values.forEach(function(x) { duplicates[x] = (duplicates[x] || 0) + 1; });
for (const key of Object.keys(duplicates)) {
if(duplicates[key] == 2) { vertices.push(key); }
else if(duplicates[key] == 3) { peak = key; }
}
return [ Number(vertices[0]), Number(vertices[1]) ];
}
它返回几何边缘上的所有顶点索引。工作正常,但很慢。 什么可以优化加快速度?
答案 0 :(得分:2)
问题的初始代码检查每个几何面的所有几何面,以确定一对相邻面和相应的边。虽然这提取了所有非边界边缘,但这导致几何/网格的面数的二次算法复杂度(并且因此边缘或顶点的数量的二次复杂度)。可以删除一些额外的实际开销(例如setEdge()
函数)。
这是一个提取网格的所有边缘(这使用网格中面数的顺序的额外工作空间)的提议,具有拟线性时间复杂度(由于边缘排序,N log N)并且可能减少开销:
以下是一个可能的实现示例:
// A cube
var faces = [
{a: 0, b: 1, c: 2}, {a: 2, b: 3, c: 0}, // Front
{a: 1, b: 5, c: 6}, {a: 6, b: 2, c: 1}, // Right
{a: 5, b: 4, c: 7}, {a: 7, b: 6, c: 5}, // Back
{a: 4, b: 0, c: 3}, {a: 3, b: 7, c: 4}, // Left
{a: 3, b: 2, c: 6}, {a: 6, b: 7, c: 3}, // Top
{a: 4, b: 5, c: 1}, {a: 1, b: 0, c: 4}, // Bottom
];
function compareEdges(edge1, edge2) {
var i1 = edge1[0];
var i2 = edge2[0];
if (i1 != i2)
return i1 < i2 ? -1 : 1;
var j1 = edge1[1];
var j2 = edge2[1];
if (j1 != j2)
return j1 < j2 ? -1 : 1;
return 0;
}
function discardUniqueEdges(edges) {
var i, j, n;
var count;
edges.sort(compareEdges);
count = 0;
j = 0; // The range [0, j[ of the array stores duplicated edges
for (i = 0, n = edges.length; i < n; i++) {
if (!count) {
count = 1;
continue;
}
if (!compareEdges(edges[i - 1], edges[i])) {
++count;
continue;
}
// edges[i - 1] != edges[i]
if (count <= 1)
continue;
// edges[i - 1] != edges[i] && count > 1
edges[j][0] = edges[i - 1][0];
edges[j][1] = edges[i - 1][1];
j += 1;
count = 1;
}
if (count > 1) {
edges[j][0] = edges[i - 1][0];
edges[j][1] = edges[i - 1][1];
j += 1;
}
edges.length = j;
return edges;
}
function extractEdges(faces) {
var edges = [];
var face;
var i, n;
// Store all edges
for (i = 0, n = faces.length; i < n; i++) {
face = faces[i];
edges.push([face.a, face.b].sort());
edges.push([face.b, face.c].sort());
edges.push([face.c, face.a].sort());
}
return discardUniqueEdges(edges);
}
var edges = extractEdges(faces);
console.log(edges.length)
console.log(edges)
答案 1 :(得分:0)
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.put(Context.PROVIDER_URL, "mq://localhost:7676");
props.put("connectionFactoryNames" , "TestQueueConnectionFactory");
props.put("queue." + "TestQueue", "TestQueue");
InitialContext ic = new InitialContext(props);
ConnectionFactory qFactory = (ConnectionFactory) ic.lookup("TestQueueConnectionFactory");
Queue queue = (Queue ) ic.lookup("TestQueue");
我尝试添加另一个参数[2]作为重复计数器,并在您的extractEdges()函数之后对边缘进行排序,以捕获那些没有副本的内容。
答案 2 :(得分:0)
function discardUniqueEdges(edges) {
var hash = {};
for(var i = 0, l = edges.length; i < l; i++){
var ab = [edges[i][0], edges[i][1]];
if (!(ab in hash)) { hash[ab] = 1; }
if((ab in hash)) { hash[ab]++; }
}
var sorted = [];
Object.keys(hash).forEach(function(key) {
if (hash[key] == 2) { sorted.push(key.split(",")); }
});
return sorted;
}
除@ user3146587提案外,此方法也很有用。