Skip to content

Commit 258ff40

Browse files
committed
foo
1 parent 9bf5513 commit 258ff40

File tree

1 file changed

+71
-71
lines changed

1 file changed

+71
-71
lines changed

svg2poly.py

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,7 @@
1010
def comparison(a,b):
1111
return 1 if a>b else (-1 if a<b else 0)
1212

13-
def compare(a,b,comparison,comparisonCache):
14-
if (a,b) in comparisonCache:
15-
return -1
16-
elif (b,a) in comparisonCache:
17-
return 1
18-
else:
19-
d = comparison(a,b)
20-
if d < 0:
21-
comparisonCache.add((a,b))
22-
else:
23-
comparisonCache.add((b,a))
24-
25-
def safeSorted(data,comparison,comparisonCache=set()):
13+
def safeSorted(data,comparison):
2614
"""
2715
A simpleminded recursive merge sort that will work even if the comparison function fails to be a partial order.
2816
Makes (shallow) copies of the data, which uses more memory than is absolutely necessary. In the intended application,
@@ -32,13 +20,13 @@ def safeSorted(data,comparison,comparisonCache=set()):
3220
n = len(data)
3321
if n <= 1:
3422
return list(data)
35-
d1 = safeSorted(data[:n//2],comparison,comparisonCache=comparisonCache)
36-
d2 = safeSorted(data[n//2:],comparison,comparisonCache=comparisonCache)
23+
d1 = safeSorted(data[:n//2],comparison)
24+
d2 = safeSorted(data[n//2:],comparison)
3725
i1 = 0
3826
i2 = 0
3927
out = []
4028
while i1 < len(d1) and i2 < len(d2):
41-
if compare(d1[i1], d2[i2], comparison, comparisonCache) < 0:
29+
if compare(d1[i1], d2[i2], comparison) < 0:
4230
out.append(d1[i1])
4331
i1 += 1
4432
else:
@@ -50,68 +38,68 @@ def safeSorted(data,comparison,comparisonCache=set()):
5038
out += d2[i2:]
5139
return out
5240

41+
def closed(path):
42+
return path[-1] == path[0]
43+
44+
def inside(z, path):
45+
for p in path:
46+
if p == z:
47+
return False
48+
try:
49+
phases = sorted((cmath.phase(p-z) for p in path))
50+
# make a ray that is relatively far away from any points
51+
if len(phases) == 1:
52+
# should not happen
53+
bestPhase = phases[0] + math.pi
54+
else:
55+
bestIndex = max( (phases[i+1]-phases[i],i) for i in range(len(phases)-1))[1]
56+
bestPhase = (phases[bestIndex+1]+phases[bestIndex])/2.
57+
ray = cmath.rect(1., bestPhase)
58+
rotatedPath = tuple((p-z) / ray for p in path)
59+
# now we just need to check shiftedPath's intersection with the positive real line
60+
s = 0
61+
for i,p2 in enumerate(rotatedPath):
62+
p1 = rotatedPath[i-1]
63+
if p1.imag == p2.imag:
64+
# horizontal lines can't intersect positive real line once phase selection was done
65+
continue
66+
# (1/m)y + xIntercept = x
67+
reciprocalSlope = (p2.real-p1.real)/(p2.imag-p1.imag)
68+
xIntercept = p2.real - reciprocalSlope * p2.imag
69+
if xIntercept == 0:
70+
return False # on boundary
71+
if xIntercept > 0:
72+
if p1.imag < p2.imag:
73+
s += 1
74+
else:
75+
s -= 1
76+
return s != 0
77+
78+
except OverflowError:
79+
return False
80+
81+
def nestedPaths(path1, path2):
82+
if not closed(path2):
83+
return False
84+
k = min(pointsToCheck, len(path1))
85+
for point in sample(path1, k):
86+
if inside(point, path2):
87+
return True
88+
return False
89+
90+
def fixPath(path):
91+
out = [complex(point[0],point[1]) for point in path]
92+
if out[0] != out[-1] and abs(out[0]-out[-1]) <= tolerance:
93+
out.append(out[0])
94+
return out
95+
5396
def comparePaths(path1,path2,tolerance=0.05,pointsToCheck=3):
5497
"""
5598
outer paths come before inner ones
5699
open ones before closed paths
57100
otherwise, top to bottom bounds, left to right
58101
"""
59102

60-
def fixPath(path):
61-
out = [complex(point[0],point[1]) for point in path]
62-
if out[0] != out[-1] and abs(out[0]-out[-1]) <= tolerance:
63-
out.append(out[0])
64-
return out
65-
66-
def closed(path):
67-
return path[-1] == path[0]
68-
69-
def inside(z, path):
70-
for p in path:
71-
if p == z:
72-
return False
73-
try:
74-
phases = sorted((cmath.phase(p-z) for p in path))
75-
# make a ray that is relatively far away from any points
76-
if len(phases) == 1:
77-
# should not happen
78-
bestPhase = phases[0] + math.pi
79-
else:
80-
bestIndex = max( (phases[i+1]-phases[i],i) for i in range(len(phases)-1))[1]
81-
bestPhase = (phases[bestIndex+1]+phases[bestIndex])/2.
82-
ray = cmath.rect(1., bestPhase)
83-
rotatedPath = tuple((p-z) / ray for p in path)
84-
# now we just need to check shiftedPath's intersection with the positive real line
85-
s = 0
86-
for i,p2 in enumerate(rotatedPath):
87-
p1 = rotatedPath[i-1]
88-
if p1.imag == p2.imag:
89-
# horizontal lines can't intersect positive real line once phase selection was done
90-
continue
91-
# (1/m)y + xIntercept = x
92-
reciprocalSlope = (p2.real-p1.real)/(p2.imag-p1.imag)
93-
xIntercept = p2.real - reciprocalSlope * p2.imag
94-
if xIntercept == 0:
95-
return False # on boundary
96-
if xIntercept > 0:
97-
if p1.imag < p2.imag:
98-
s += 1
99-
else:
100-
s -= 1
101-
return s != 0
102-
103-
except OverflowError:
104-
return False
105-
106-
def nestedPaths(path1, path2):
107-
if not closed(path2):
108-
return False
109-
k = min(pointsToCheck, len(path1))
110-
for point in sample(path1, k):
111-
if inside(point, path2):
112-
return True
113-
return False
114-
115103
path1 = fixPath(path1)
116104
path2 = fixPath(path2)
117105

@@ -130,6 +118,18 @@ def nestedPaths(path1, path2):
130118
else:
131119
return comparison(y1,y2)
132120

121+
def orderedPaths(sortedPaths):
122+
level = []
123+
while len(sortedPaths):
124+
path = sortedPaths[0]
125+
if closed(path):
126+
for p in level:
127+
if inside(path, p):
128+
return [level] + orderedPaths(sortedPaths)
129+
level.append(path)
130+
sortedPaths.pop(0)
131+
return [level]
132+
133133
def message(string):
134134
if not quiet:
135135
sys.stderr.write(string + "\n")

0 commit comments

Comments
 (0)