-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfaces.py
More file actions
105 lines (73 loc) · 1.8 KB
/
faces.py
File metadata and controls
105 lines (73 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""Compute the faces of a planar graph."""
import cmath
class Vec:
def __init__(v, x, y):
v.c = complex(x, y)
@property
def x(v):
return v.c.real
@property
def y(v):
return v.c.imag
@staticmethod
def _from_real(c):
return Vec(c.real, c.imag)
def __sub__(v1, v2):
return v1._from_real(v1.c - v2.c)
@property
def length(v):
return abs(v.c)
@property
def theta(v):
return cmath.phase(v.c)
def __repr__(v):
return f"Vec({v.x}, {v.y})"
def is_outer(face):
global left, right, top, bottom
for v in left, right, top, bottom:
if v[0] not in face:
return False
return True
def rel_theta(origo):
return lambda p: (p.point - origo).theta
def sort_neighborhood(v, nv):
pv = G.vertices[v]
neighbors = sorted([Vertex(u, G.vertices[u]) for u in nv], key=rel_theta(pv))
return [u.name for u in neighbors]
def sort_all_neighborhoods(G):
for v, nv in G.edges.items():
G.edges[v] = sort_neighborhood(v, nv)
sort_all_neighborhoods(G)
def cycle(s):
m = min(s)
i = s.index(m)
return s[i:] + s[:i]
def get_face(edge, G):
face = [edge[0]]
while True:
u, v = edge
if v in face:
break
face.append(v)
nb = G.edges[v]
ui = nb.index(u)
nxt = nb[(ui + 1) % len(nb)]
edge = v, nxt
return face
faces = {}
for v, nv in G.edges.items():
for u in nv:
edge = v, u
faces[edge] = tuple(cycle(get_face(edge)))
def get_polygon(edge, G):
f = faces[edge]
poly = []
for v in f:
poly.append(G.vertices[v])
return poly
def face_to_polygon(face, G):
poly = []
for v in face:
poly.append(G.vertices[v])
return poly
G = None