多边形指数列表中的邻域多边形

时间:2012-01-13 05:50:40

标签: 3d polygon mesh

我的网格形式为this。 以及表示末尾每个多边形的索引列表。我需要为每个多边形生成一个相邻多边形的列表,并且想知道是否有人知道这样做的有效算法?

最简单的方法是每个多边形,检查每个其他多边形是否有两个匹配的索引 - 但这看起来像是涉及一些嵌套循环。我不介意使用它,性能在这里不是一个大问题,但是,我只是在寻找替代方案。

每个多边形的最大索引/顶点没有任何限制,但为了简单起见,我们假设它是3(所以三角形多边形)。

感谢您的帮助! :)

3 个答案:

答案 0 :(得分:4)

哎呀,XML网格:)。

我实际上对此很好看,我的第一个答案很懒散。你可以写得更好(如上所述),并没有那么复杂,我不会为这篇期刊文章支付40美元。这是一个适合您的伪代码解决方案。

注意:当我说表时,我的意思是'查找表'。

假设每个三角形都被编号并由顶点v1,v2,v3组成,这些顶点是唯一编号的并且可以使用<运算符(因此我们可以获得唯一的键组合)。

我们需要两个查找表:

  • edge->(三角形列表)表名为edge_triangles。
  • 一个名为triangle_edges的三角形 - >(边缘列表)表。

一个表格,它告诉我们哪个三角形使用给定的边缘,另一个告诉我们哪个边缘是由给定的三角形组成的。我们按如下方式构建这些列表:

for t = next triangle
    // Determine the ordering of vertices.
    min_vertex = min(t.v1, t.v2, t.v3);
    mid_vertex = median(p.v1, t.v2, t.v3);
    max_vertex = max(t.v1, t.v2, t.v3);

    // Register which edges this triangle uses.
    edge_triangles[min_vertex][mid_vertex].append(t);
    edge_triangles[mid_vertex][max_vertex].append(t);
    edge_triangles[min_vertex][max_vertex].append(t);

    // Set the edges that make up this triangle.
    triangle_edges[t].append({min_vertex, mid_vertex});
    triangle_edges[t].append({mid_vertex, max_vertex});
    triangle_edges[t].append({min_vertex, max_vertex});
for next t

使用这些列表,我们可以获取给定三角形中的边,将它们用作边表中的键,并查看哪些多边形共享该边。因此,相邻的三角形。因此,对于三角形,我们可以执行以下操作:

adjacent = edge_faces[face_edges[t][0]];

这是'邻近的伪代码等于共享三角形t'的第0个边的三角形列表,其中第0个只是第一个。

我们使用min,median和max来确保我们没有相同边的不同条目:例如{v1,v2}和{v2,v1},其中v1和v2是两个顶点。我们实际上可以忽略这一点并添加一个“紧凑”步骤,其中我们连接列表,这些列表对应于边缘列表中的不同条目,但实际上对应于相同的边缘。

另一个可能的问题是,如果您有两条重合但不共享公共顶点的边。在这种情况下,您可以将任一边减少到参数方程,比较它们的重合,并形成一个查找表,告诉您,对于给定边,哪些边是重合的,所以map:

  • edge->(边缘列表)表名为edge_coincident_edges。

我们使用另一个查找表,因为我们无法连接edge-> faces表。如果边e1和e2相邻,则e2和e3是,但是e1和e3不是。如果我们连接edge-> face列表中的e1,e2和e3条目,你最终会得到一些非常不正确的数据。这可能比你想做的多一点,但这是我今天早上要解决的问题:)。

在每个边缘只能对应最多2个三角形的情况下,我们可以取消传统意义上的'list',我们可以追加,并使用大小为2的固定大小的数组。这将减少你的内存开销和提高内存效率。所以我们的边缘表更类似于:

  • edge->(第一个三角形,第二个三角形)表名为edge_triangles。

无论如何,基本算法可扩展到任意数量的具有任意数量边的多边形(在所有多边形之间不一定相同),并且相对于三角形(或一般多边形)的数量是O(N)时间案件)。空间复杂度为O(E + N)其中E为边,N为多边形数。假设你有很好的散列算法,查找时间应该接近O(1)。

答案 1 :(得分:1)

如果您只对三角网格(或 n -D中的任何单纯形式)感兴趣,那么实际上有更快的解决方案!您建议的时间复杂度为O( k ^ 2),其中 k 是三角形的数量。这意味着对于大量三角形,计算邻居所需的时间增加了二次方,这在大多数情况下在计算上是禁止的。

我建议你阅读Ueng和Sikorski的文章("关于构建3D FEA数据邻接图的线性时间算法的注释",视觉计算机 12 :pp.445-450,1996)。作者解释了一个线性时间算法O( k ),用于在四面体网格中找到邻居,从中可以很容易地推导出类似于三角网​​格的算法。也许你也可以将它扩展为一般多边形!

请告诉我这是否适合您!

答案 2 :(得分:0)

如果没有预先计算好的数据,就不可能比循环遍历所有面孔更快。

对于预先计算的数据,每个顶点都足以容纳使用它的面列表。使用2个顶点的交叉面列表完成查找邻居。