This commit is contained in:
jaseg 2025-12-16 14:26:45 +01:00
parent 3e6c7d6f57
commit 556707dc35

View file

@ -253,54 +253,79 @@ class Skeletonator:
if r2 is None:
r2 = self.min_radius
if t2 < t1:
t1, t2 = t2, t1
r1, r2 = r2, r1
def r_interpolate(t):
f = (t - t1) / (t2 - t1)
f = min(1, max(0, f)) # Clip to start/end of spiral
return r1 + (r2 - r1) * f
turn_range = list(range(math.floor(min(t1, t2)), math.ceil(max(t1, t2))+1))
if t2 < t1:
turn_range = list(reversed(turn_range))
print(f' {turn_range=}')
for t_start, t_end in zip(turn_range, turn_range[1:]):
r_start = r_interpolate(t_start)
r_end = r_interpolate(t_end)
r_ref = r_start
_ic_arcs, inner_circumference = self.map_circumference(r_ref)
print(f' {r_ref=} {r_start=} {r_end=}')
r_ref = min(r1, r2) # r_start, r_end) # Handle outward spirals where the radii are swapped
_ic_arcs, inner_circumference = self.map_circumference(r_ref)
inner_circumference_sum = sum(math.dist(p1, p2) for p1, p2 in edge_cycle(inner_circumference))
angle = t_start
circumference_angles = []
inner_circumference_sum = sum(math.dist(p1, p2) for p1, p2 in edge_cycle(inner_circumference))
point_angles = [t_start]
for p1, p2 in edge_cycle(inner_circumference):
edge_angle = math.dist(p1, p2) / inner_circumference_sum
point_angles.append(angle)
angle += edge_angle
angle = 0
point_angles = [0]
for p1, p2 in edge_cycle(inner_circumference):
edge_angle = math.dist(p1, p2) / inner_circumference_sum
point_angles.append(angle)
angle += edge_angle
edge_angles = list(zip(self.poly_edges, itertools.pairwise(point_angles)))
if t2 < t1:
edge_angles = reversed(edge_angles)
for (p1, p2), (tp1, tp2) in edge_angles:
_oc_arcs, outer_circumference = self.map_circumference(max(r1, r2))
outer_circumference_sum = sum(math.dist(p1, p2) for p1, p2 in edge_cycle(outer_circumference))
angle = 0
point_angles_outer = [0]
for p1, p2 in edge_cycle(outer_circumference):
edge_angle = math.dist(p1, p2) / outer_circumference_sum
point_angles_outer.append(angle)
angle += edge_angle
for ia1, ia2, oa1, oa2 in zip(point_angles, point_angles[1:] + [1], point_angles_outer, point_angles_outer[1:] + [1]):
t_map = t1 if r1 > r2 else t2
t_map_int = math.floor(t_map)
t_map %= 1.0
if approx_in_range(t_map, oa1, oa2):
if oa1 == oa2:
t_mapped = ia1
else:
t_mapped = ia1 + (ia2 - ia1) * ((t_map - oa1) / (oa2 - oa1))
#if r1 > r2:
#t1 = t_mapped + t_map_int
#else:
#t2 = t_mapped + t_map_int
print(f'mapped {t_map=:.3f} to {t_mapped=:.3f}')
break
turn_angles = range(math.floor(t1), math.ceil(t2) + 1)
for t_start, t_end in zip(turn_angles, turn_angles[1:]):
t_end = t_start + 1
for (p1, p2), (tp1, tp2) in zip(self.poly_edges, itertools.pairwise(point_angles)):
tp1, tp2 = tp1 + t_start, tp2 + t_start
rp1 = r_interpolate(tp1)
rp2 = r_interpolate(tp2)
_arc, p1_proj = self.project_arc(p1, rp1)
_arc, p2_proj = self.project_arc(p2, rp2)
if approx_in_range(t1, min(tp1, tp2), max(tp1, tp2)):
if approx_in_range(t1, tp1, tp2):
_arc, p2_proj_r1 = self.project_arc(p2, r1)
yield interpolate(p1_proj, p2_proj_r1, t1, tp1, tp2), r_ref
if approx_in_range(t2, min(tp1, tp2), max(tp1, tp2)):
if approx_in_range(t2, tp1, tp2):
_arc, p1_proj_r2 = self.project_arc(p1, r2)
yield interpolate(p1_proj_r2, p2_proj, t2, tp1, tp2), r_ref
elif approx_in_range(tp2, min(t1, t2), max(t1, t2)):
elif approx_in_range(tp2, t1, t2):
yield p2_proj, r_ref
def dump_to_pdf(self, filename):
with PdfPages(filename) as pdf:
fig, ax = plt.subplots(figsize=(10, 10))
# polygon outline
# polygon outliner
poly_x = [p[0] for p in self.poly] + [self.poly[0][0]]
poly_y = [p[1] for p in self.poly] + [self.poly[0][1]]
ax.plot(poly_x, poly_y, 'b-', linewidth=2, label='Polygon')