哎呀,XML网格 :).
我仔细看了一下,我第一个答案太懒了。你可以写得更好(如上所述),而且它并不复杂,我不会为此花费40美元购买期刊文章。这里是一个伪代码解决方案,应该适合你。
注意: 我说的“表”是指“查找表”。
假设每个三角形都有编号,并由顶点v1、v2、v3组成,这些顶点具有唯一编号,可以使用<运算符进行比较(因此我们可以获得唯一的键组合)。
我们需要两个查找表:
- 一个名为edge_triangles的边->(三角形列表)表。
- 一个名为triangle_edges的三角形->(边列表)表。
一个告诉我们哪些三角形使用给定边的表,另一个告诉我们给定三角形由哪些边组成。我们按以下方式构建这些列表:
for t = next triangle
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);
edge_triangles[min_vertex][mid_vertex].append(t);
edge_triangles[mid_vertex][max_vertex].append(t);
edge_triangles[min_vertex][max_vertex].append(t);
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
使用这些列表,我们可以将给定三角形中的边作为键用于边表,并查看哪些多边形共享该边。因此,就得到了相邻的三角形。因此,对于三角形t,我们可以执行以下操作:
adjacent = edge_faces[face_edges[t][0]]
这是伪代码,“邻边等于三角形列表,这些三角形共享三角形t的第一个边”,其中0是指第一个。
我们使用min、median和max来确保对于相同边不会有不同的条目:例如{v1,v2}和{v2,v1},其中v1和v2是两个顶点。事实上,我们可以忽略这一点,并添加一个“紧缩”步骤,其中我们连接对应于我们的边缘列表中的不同条目但实际上对应于相同边缘的列表。
另一个可能的问题是,如果你有两条重合的边却没有共同的顶点。在这种情况下,你可以将任一边减少到一个参数方程,比较它们是否重合,并形成一个查找表,告诉你给定边,哪些边是重合的,所以映射:
边 - > (边缘列表)称为edge_coincident_edges的表格。
我们使用了另一个查找表,因为我们不能连接边缘- >面表。考虑如果边缘e1和e2相邻,e2和e3相邻,但e1和e3不相邻。 如果我们在边缘- >面列表中连接e1、e2和e3条目,你会得到一些极其不正确的数据。虽然这可能比你想做的要多一些,但这是我今天早上要解决的问题:)。
在每条边最多只能对应于2个三角形的情况下,我们可以摒弃传统意义上的“列表”,使用大小为2的固定大小数组。这将减少内存开销并提高内存效率。因此,我们的边缘表更类似于:
边 - >(第一个三角形,第二个三角形)称为edge_triangles的表格。
无论如何,基本算法都可扩展到任何具有任何数量边缘的多边形,并且与三角形(或一般情况下多边形)的数量成比例地为O(N)时间。空间复杂度为O(E + N),其中E是边数,N是多边形数。假设你有良好的哈希算法,查找时间应该接近O(1)。