1
- import enum
2
1
import typing
3
2
4
3
strings = [
5
4
"""
5
+ #########################
6
+ #########################
7
+ #########################
8
+ #########################
9
+ #########################
10
+ #########################""" ,
11
+ """
12
+ #########################
13
+ #########################
14
+ #############
15
+ #########################
16
+ #########################
17
+ """ ,
18
+ """
6
19
#
7
20
###
8
21
#####
87
100
"""
88
101
###############
89
102
###################
90
- ###############""" ]
103
+ ###############""" ,
104
+ """
105
+ ################
106
+ ################
107
+ ################
108
+ ################
109
+ ################
110
+ ################
111
+ ################
112
+ ################""" ,
113
+ """
114
+ # # # # # # # #
115
+ ################
116
+ ################
117
+ ################
118
+ ################
119
+ ################
120
+ # # # # # # # #""" ,
121
+ """
122
+ #
123
+ ####
124
+ #######
125
+ ##########
126
+ #############
127
+ ################
128
+ ###################
129
+ ######################
130
+ #########################
131
+ ######################
132
+ ###################
133
+ ################
134
+ #############
135
+ ##########
136
+ #######
137
+ ####
138
+ #""" ]
91
139
92
140
"""
93
141
idea for new algorithm
@@ -170,9 +218,9 @@ def cull_disallowed_edges(
170
218
# (the above algorithm has some weird edge cases where it may produce
171
219
# one-way edges on accident)
172
220
# XXX This causes issues when it is enabled, why?
173
- for p1 in all_points :
174
- for p2 in fixed_edges . setdefault ( p1 , set ()) :
175
- fixed_edges .setdefault (p2 , set ()).add (p1 )
221
+ for p , c in fixed_edges . items () :
222
+ for q in c :
223
+ fixed_edges .setdefault (q , set ()).add (p )
176
224
return fixed_edges
177
225
178
226
@@ -186,7 +234,6 @@ def walk_graph_to_loop(
186
234
swd_into : dict [complex , set [complex ]] = {}
187
235
while not all (e in out for e in edges ) or current != start :
188
236
out .append (current )
189
- print (debug_singular_polyline_in_svg (out , current ))
190
237
# log the direction we came from
191
238
swd_into .setdefault (current , set ()).add (current_dir )
192
239
choices_directions = (rot (current_dir , i )
@@ -198,23 +245,22 @@ def walk_graph_to_loop(
198
245
if nxt in edges [current ]:
199
246
if nxt not in swd_into .keys ():
200
247
# if we haven't been there before, go there
201
- print ("go new place" )
202
248
current = nxt
203
249
current_dir = d
204
250
break
205
251
# otherwise, if we've been there before, but haven't
206
252
# come from this direction, then save it for later
207
253
if d not in swd_into .get (nxt , set ()) and bt_d is None :
208
254
bt_d = d
209
- print ("saving" , d )
210
255
else :
211
256
if bt_d is not None :
212
257
# if we have a saved direction to go, go that way
213
258
current = current + bt_d
214
259
current_dir = bt_d
215
260
else :
216
261
raise RuntimeError
217
- print ("finished normally" )
262
+ print ("path clockwise is" )
263
+ print (debug_singular_polyline_in_svg (out , current ))
218
264
return out
219
265
220
266
@@ -262,13 +308,14 @@ def remove_unnecessary(pts: list[complex],
262
308
# numbers for all others
263
309
maxima = [is_mid_maxima (a , b , c ) for (a , b , c ) in triples (distances )]
264
310
points_to_maybe_discard = set (
265
- pt for ( pt , dist , maxima ) in zip (pts , distances , maxima )
311
+ pt for pt , dist , maxima , pointy in zip (pts , distances , maxima , dotnos )
266
312
# keep all the local maxima
267
313
# keep ones that are flat enough
268
314
# --> remove the ones that are not sloped enough
269
315
# and are not local maxima
270
316
if ((dist is not None and dist < maxslope )
271
- and not maxima ))
317
+ and not maxima
318
+ and pointy != 0 ))
272
319
# the ones to definitely keep are the convex ones
273
320
# as well as concave ones that are adjacent to only straight ones that
274
321
# are being deleted
@@ -281,7 +328,7 @@ def remove_unnecessary(pts: list[complex],
281
328
# special case: keep concave ones that are 2-near at
282
329
# least one convex pointy point (where pointy additionally means that
283
330
# it isn't a 180)
284
- points_to_def_keep |= set (
331
+ points_to_def_keep . update ( set (
285
332
p for (
286
333
p ,
287
334
(dot_2l , _ , _ , _ , dot_2r ),
@@ -290,27 +337,33 @@ def remove_unnecessary(pts: list[complex],
290
337
) in zip (pts , fiveles (dotnos ), fiveles (signos ), fiveles (dirs ))
291
338
if sig_m < 0 and (
292
339
(sig_2l > 0 and dot_2l < 0 and dd1_2l != - dd2_2l )
293
- or (sig_2r > 0 and dot_2r < 0 and dd1_2r != - dd2_2r )))
340
+ or (sig_2r > 0 and dot_2r < 0 and dd1_2r != - dd2_2r ))))
294
341
# for debugging
295
342
a = dots ([], edges )
296
343
i = a .replace ("</svg>" , "" .join (f"""<circle cx="{
297
- p .real
344
+ pt .real
298
345
} " cy="{
299
- p .imag
300
- } " r="0.5" fill="{
301
- "red" if r > 0
302
- else "blue" if r < 0
346
+ pt .imag
347
+ } " r="{
348
+ 0.5 if conc == 0
349
+ else 0.8 if conc > 0
350
+ else 0.2
351
+ } " fill="{
352
+ "red" if sharp > 0
353
+ else "blue" if sharp < 0
303
354
else "black"
304
355
} " opacity="50%"></circle>"""
305
- for p , q , r in zip (pts , distances , dotnos )) + "</svg>" )
356
+ for pt , sharp , conc in zip (pts , dotnos , signos )) + "</svg>" )
306
357
z = a .replace ("</svg>" , "" .join (f"""<circle cx="{
307
358
p .real
308
359
} " cy="{
309
360
p .imag
310
361
} " r="0.5" fill="red" opacity="50%"></circle>"""
311
362
for p in (points_to_maybe_discard - points_to_def_keep )) + "</svg>" )
312
- print ("begin conc" , i , "end conc" )
313
- print ("begin discard" , z , "end discard" )
363
+ print ("pointyness / concavity" )
364
+ print (i )
365
+ print ("will be discarded" )
366
+ print (z )
314
367
# end debugging
315
368
return [p for p in pts
316
369
if p not in points_to_maybe_discard
@@ -332,11 +385,12 @@ def process_group(g: list[complex], all_pts: list[complex]) -> list[complex]:
332
385
333
386
def get_outline_points (pts : list [complex ]) -> list [list [complex ]]:
334
387
# find the edge points
335
- edge_points : list [complex ] = []
388
+ edge_points : set [complex ] = set ()
336
389
for p in pts :
337
- if not all (p + d in pts for d in DIRECTIONS ) and not all (
338
- p + d in pts for d in VN_DIRECTIONS ):
339
- edge_points .append (p )
390
+ if not all (p + d in pts for d in DIRECTIONS ):
391
+ if not all (
392
+ p + d in pts for d in VN_DIRECTIONS ):
393
+ edge_points .add (p )
340
394
# find all of the disconnected loop groups
341
395
loop_groups : list [list [complex ]] = []
342
396
while edge_points :
@@ -376,32 +430,28 @@ def debug_singular_polyline_in_svg(
376
430
points : list [complex ], current : complex , scale : float = 20 ) -> str :
377
431
vbx = max (x .real for x in points ) + 1
378
432
vby = max (x .imag for x in points ) + 1
379
- return f"""<svg viewBox="-1 -1 { vbx + 2 } { vby + 2 } " width="{
380
- vbx * scale } " height="{ vby * scale } "><polyline
381
- fill="none"
382
- stroke="black"
383
- stroke-width="0.1"
384
- points="{ " " .join (map (lambda x : f"{ x .real } ,{ x .imag } " , points ))} ">
385
- </polyline><circle cx="{ current .real } " cy="{
433
+ return (f"""<svg viewBox="-1 -1 { vbx + 2 } { vby + 2 } " width="{
434
+ vbx * scale } " height="{ vby * scale } "><polyline fill="none" """
435
+ f"""stroke="black" stroke-width="0.1" points="{
436
+ " " .join (map (lambda x : f"{ x .real } ,{ x .imag } " , points ))
437
+ } "></polyline><circle cx="{ current .real } " cy="{
386
438
current .imag
387
- } " r="0.3" fill="blue" /></svg>"""
439
+ } " r="0.3" fill="blue" /></svg>""")
388
440
389
441
390
442
def example (all_points : list [complex ], scale : float = 20 ) -> str :
391
443
ps = get_outline_points (all_points )
392
444
vbx = max (x .real for p in ps for x in p ) + 1
393
445
vby = max (x .imag for p in ps for x in p ) + 1
394
- polylines = "" .join (f"""<polyline
395
- fill="none"
396
- stroke="black"
397
- stroke-width="0.1"
398
- points="{ " " .join (map (lambda x : f"{ x .real } ,{ x .imag } " , p ))} ">
399
- </polyline>""" for p in ps )
400
- return f"""<svg
401
- viewBox="-1 -1 { vbx + 2 } { vby + 2 } "
402
- width="{ vbx * scale } "
403
- height="{ vby * scale } ">
404
- { polylines } </svg>"""
446
+ polylines = "" .join ("""<polyline fill="none" stroke="black" """
447
+ f"""stroke-width="0.1" points="{
448
+ " " .join (map (lambda x : f"{ x .real } ,{ x .imag } " ,
449
+ p + [p [0 ]]))
450
+ } "></polyline>""" for p in ps )
451
+ print ("final" )
452
+ return f"""<svg viewBox="-1 -1 { vbx + 2 } { vby + 2 } " width="{
453
+ vbx * scale
454
+ } " height="{ vby * scale } ">{ polylines } </svg>"""
405
455
406
456
407
457
print ("<style>svg { border: 1px solid black}body{white-space: pre}</style>" )
0 commit comments