【问题标题】:Efficiently find twin edges in Half-Edge (DCEL) data structure?在半边(DCEL)数据结构中有效地找到双边?
【发布时间】:2019-02-14 07:13:04
【问题描述】:

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

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

具体来说,链接半边的过程似乎占用了最多的时间。 我想就如何改进我的算法获得一些建议。

下面是我用来初始化我的数据结构的代码。第一个 for 循环使用顶点数据创建一个 Face,同时将构成 Face 的 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

这是实际的代码

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());

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

【问题讨论】:

    标签: javascript algorithm three.js


    【解决方案1】:

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

    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);
    }
    
    

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 2018-09-25
      • 2012-09-03
      • 2016-05-24
      • 2013-02-28
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多