在半边(DCEL)数据结构中有效地找到双边?

时间:2019-02-13 20:14:52

标签: javascript algorithm three.js

我正在使用HalfEdge数据结构来表示网格上面之间的连通性。

我正在导入一个外部模型,并且在导入过程中正在构建HalfEdge结构。但是,对于具有许多三角形的网格,构建过程会占用太多时间。

具体来说,似乎连接半边的过程最多。 我想获得一些有关如何改进算法的建议。

下面是我用来初始化数据结构的代码。第一个for循环使用顶点数据创建一个Face,同时将组成console.log('start constructing DCEL', new Date().toTimeString()); // initialize Half-Edge data structure (DCEL) const initialFaceColor = new THREE.Color(1, 1, 1); const { position } = geometry.attributes; const faces = []; const edges = []; let newFace; console.log('start making faces', new Date().toTimeString()); for (let faceIndex = 0; faceIndex < (position.count / 3); faceIndex++) { newFace = new Face().create( new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 0), new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 1), new THREE.Vector3().fromBufferAttribute(position, faceIndex * 3 + 2), faceIndex); edges.push(newFace.edge); edges.push(newFace.edge.next); edges.push(newFace.edge.prev); newFace.color = initialFaceColor; faces.push(newFace); } console.log('end making faces', new Date().toTimeString()); console.log('start linking halfEdges', new Date().toTimeString()); /** * Find and connect twin Half-Edges * * if two Half-Edges are twins: * Edge A TAIL ----> HEAD * = = * Edge B HEAD <---- TAIL */ let currentEdge; let nextEdge; for (let j = 0; j < edges.length; j++) { currentEdge = edges[j]; // this edge has a twin already; skip to next one if (currentEdge.twin !== null) continue; for (let k = j + 1; k < edges.length; k++) { nextEdge = edges[k]; // this edge has a twin already; skip to next one if (nextEdge.twin !== null) continue; if (currentEdge.head().equals(nextEdge.tail()) && currentEdge.tail().equals(nextEdge.head())) { currentEdge.setTwin(nextEdge); } } } console.log('end linking halfEdges', new Date().toTimeString()); console.log('end constructing DCEL', new Date().toTimeString()); 的HalfEdges推入一个单独的数组中,稍后再使用。

第二个for循环负责调查所有HalfEdges的数组,并找到匹配的对(即,彼此成对的两个)。

我注销了每个过程之前和之后的时间,并注意到第二个循环使一切变慢。

这是时间戳记

  

开始构建DCEL 14:55:22

     

开始做鬼脸14:55:22

     

做鬼脸14:55:22

     

/ *这是要花很长时间的地方。在具有13000个三角形的网格上,将近6秒* /

     

开始链接HalfEdges 14:55:22

     

结束链接HalfEdges 14:55:28

     

结束构建DCEL 14:55:28

这是实际代码

{{1}}

如何优化搜索双边缘的过程?

1 个答案:

答案 0 :(得分:2)

我会尝试哈希并查找边缘,例如像这样:

function hash(p1, p2) {
  return JSON.stringify(p1)+JSON.stringify(p2);
}
const lookup = {}
for (let j = 0; j < edges.length; j++) {
  lookup[hash(edge.head(), edge.tail())] = edge;
}
for (let j = 0; j < edges.length; j++) {
  const twin = lookup[hash(edge.tail(), edge.head())];
  !edge.twin && twin && !twin.twin && edge.setTwin(twin);
}