Eri*_*ric 13 python geometry graph-theory
我有一些看起来像这样的数据:
vertex_numbers = [1, 2, 3, 4, 5, 6]
# all order here is unimportant - this could be a set of frozensets and it would
# not affect my desired output. However, that would be horribly verbose!
edges = [
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(2, 3),
(3, 4),
(4, 5),
(5, 2),
(2, 6),
(3, 6),
(4, 6),
(5, 6)
]
Run Code Online (Sandbox Code Playgroud)
上面的例子描述了一个八面体 - 对顶点1到6进行编号,其中1和6彼此相对,每个条目描述每个边的末端的顶点数.
从这些数据中,我想生成一个面部列表.面部保证是三角形的.这是上面输入的一个这样的面部列表,由手工确定:
faces = [
(1, 2, 3),
(1, 3, 4),
(1, 4, 5),
(1, 5, 2),
(2, 5, 6),
(3, 2, 6),
(4, 3, 6),
(5, 4, 6)
]
Run Code Online (Sandbox Code Playgroud)
从图形上看,这可以表示如下:

对于任何面,按照卷曲箭头的方向,您可以读取上面的顶点数字.这不适用于外表面,1, 3, 4但您可以通过在球体表面上绘图来解决这个问题
我可以接近这个:
edge_lookup = defaultdict(set)
for a, b in edges:
edge_lookup[a] |= {b}
edge_lookup[b] |= {a}
faces = set()
for a in vertex_numbers:
for b in edge_lookup[a]:
for c in edge_lookup[a]:
if b in edge_lookup[c]:
faces.add(frozenset([a, b, c]))
faces = map(tuple, faces)
Run Code Online (Sandbox Code Playgroud)
给予(从输出重新排序以便于与原始比较):
[
(1, 2, 3), # ok
(1, 3, 4), # ok
(1, 4, 5), # ok
(1, 2, 5), # cyclically incorrect!
(2, 5, 6), # ok
(2, 3, 6), # cyclically incorrect!
(3, 4, 6), # cyclically incorrect!
(4, 5, 6), # cyclically incorrect!
}
Run Code Online (Sandbox Code Playgroud)
但是,这有两个原因:
它至少是O(N³)
在这种特殊情况下,这不是问题,因为N = 10242,它在不到5秒的时间内完成
它不确定面部排序
我在frozenset那里使用s,这本身就是无序的.我需要生成与我的示例输出具有相同循环次序的面.
生成的面部序列用于使用OpenGL渲染单侧曲面.因此,所有面顶点都处于相同的旋转顺序是至关重要的(无论最终是顺时针还是逆时针是顶点本身的属性 - 我所关心的是每个面都是相同的)
它假设形成三角形的所有边都必须是面
正如@Bartosz在评论中指出的那样,情况并非如此 - 采取任何两个三角形网格,并将它们连接在一个面上,并且你有一些不再是面孔的东西.
我应该使用什么方法来构造具有正确旋转顺序的面列表?
我可以给你第二部分的线索;一旦你有了人脸,有一种简单的方法可以让它循环正确。
首先选择一张脸 (a, b, c) 是正确的,然后没有其他脸可以包含 (a, b), (b, c) 或 (c, a) 的顺序。换句话说,找到包含顶点 a, b 的面,然后使其成为 (b, a, x),依此类推。
如果你不明白我的意思 - 使用以下事实:每条边 (x, y) 由两个面包含,如果它们是循环正确的,其中一个面将其作为 (x, y),其他为 (y, x)。
可能的实现:首先创建一个图形,其中面是顶点,边意味着两个面在原始问题中共享一条边。然后使用 DFS 或 BFS。
| 归档时间: |
|
| 查看次数: |
1555 次 |
| 最近记录: |