From 556707dc35cdba0ea774892aaf99389a29651984 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 16 Dec 2025 14:26:45 +0100 Subject: [PATCH] WIP --- src/kicoil/skeletonator.py | 77 +++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/kicoil/skeletonator.py b/src/kicoil/skeletonator.py index 8f42106..68fdb93 100644 --- a/src/kicoil/skeletonator.py +++ b/src/kicoil/skeletonator.py @@ -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')