我有一些數據,看起來像這樣:如何使用一致的頂點排序從邊緣列表構造一個面的列表?
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)
]
上面的實施例描述了octohedron - 編號的頂點爲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)
]
概略地,這可以如下表示:
對於任何面,按照捲曲箭頭的方向,你可以讀出上面的頂點數。這並沒有真正的外表面,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)
給予(重新排序從輸出爲便於比較與原):
[
(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!
}
然而,這是不好的原因:
它至少O(N 3)
在這個特定的情況下,這不是一個問題,因爲N = 10242,它在小於5秒
一點也沒有完成't確定臉訂購
我在那裏使用
frozenset
,這本質上是無序的。我需要以與我的示例輸出相同的循環順序生成面。生成的臉部序列用於使用OpenGL渲染單面曲面。因此,所有面頂點必須是相同的旋轉順序(不管是順時針還是逆時針是頂點本身的屬性 - 我只關心每個面都是相同的)
它假定形成三角形必須面對一個所有邊緣
由於@Bartosz在評論中指出,這不是必須的情況下 - 採取任何兩個三角形網格,並在迎面加入他們的行列,並你擁有的東西不再是一張臉。
我應該用什麼方法來構造面的列表與正確的旋轉次數?
實現我很困惑,爲什麼'(1,2,5)'是不正確週期性,但'(1,5,2)'是不是。他們都有兩條邊,一條邊,一條邊。還是有其他決定我失蹤的週期性正確性的東西? –
@Sam:考慮將圖形展平到一個平面上 - 可以按順時針順序或逆時針方向繪製面。我應該強調'邊緣'中頂點的順序沒有意義 - 這不是一個有向圖 – Eric
我想我還是很困惑。 :-)根據你如何將圖表平面化到飛機上,這不會改變嗎?我很可能只是這種東西的小菜一碟 - 有沒有關於這種東西的參考,你可以指點我? –