diff --git a/src/kicoil/geometry.py b/src/kicoil/geometry.py index 7d17d55..fedf483 100644 --- a/src/kicoil/geometry.py +++ b/src/kicoil/geometry.py @@ -518,6 +518,7 @@ class PlanarInductor(): fold_angle = start_angle + self.sweeping_angle end_angle = fold_angle + self.sweeping_angle + print(f'### TWIST {i} INWARD ###') # Handle the spiral arm points_layer0, arm_length, angle_refs_layer0 = self.shape.compute_spiral(a1=start_angle, a2=fold_angle, fn=circle_segments) x0, y0 = points_layer0[0] @@ -533,6 +534,7 @@ class PlanarInductor(): footprint.lines.extend(kicad.make_line(*p1, *p2, self.trace_width, self.layer_pair[0]) for p1, p2 in zip(points_layer0, points_layer0[1:])) if self.layers > 1: + print(f'### TWIST {i} OUTWARD ###') # Handle the returning arm on the bottom layer points_layer1, _, angle_refs_layer1 = self.shape.compute_spiral(a1=end_angle, a2=fold_angle, fn=circle_segments) points_layer1 = points_layer1[::-1] diff --git a/src/kicoil/skeletonator.py b/src/kicoil/skeletonator.py index cb56db1..8f42106 100644 --- a/src/kicoil/skeletonator.py +++ b/src/kicoil/skeletonator.py @@ -247,50 +247,53 @@ class Skeletonator: return arcs, points def do_spiral(self, t1, t2, r1=None, r2=None): + print(f' {t1=:.5f} {t2=:.5f} {r1=:.2f} {r2=:.2f}') if r1 is None: r1 = self.radius if r2 is None: r2 = self.min_radius - if t2 < t1: - t1, t2 = t2, t1 - r1, r2 = r2, r1 - def r_interpolate(t): - t = max(t1, min(t2, t)) # Clip to start/end of spiral f = (t - t1) / (t2 - t1) + f = min(1, max(0, f)) # Clip to start/end of spiral return r1 + (r2 - r1) * f - for t_start in range(math.floor(t1), math.ceil(t2)): - t_end = t_start + 1 - r_outer = r_interpolate(t_start) - r_inner = r_interpolate(t_end) - r_ref = min(r_inner, r_outer) # Handle outward spirals where the radii are swapped + 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=}') angle = t_start circumference_angles = [] inner_circumference_sum = sum(math.dist(p1, p2) for p1, p2 in edge_cycle(inner_circumference)) - point_angles = [] + 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 - point_angles.append(t_end) - for (p1, p2), (tp1, tp2) in zip(self.poly_edges, itertools.pairwise(point_angles)): + 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: 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, tp1, tp2): + if approx_in_range(t1, min(tp1, tp2), max(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, tp1, tp2): + if approx_in_range(t2, min(tp1, tp2), max(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, t1, t2): + elif approx_in_range(tp2, min(t1, t2), max(t1, t2)): yield p2_proj, r_ref def dump_to_pdf(self, filename): diff --git a/uv.lock b/uv.lock index c28bbe4..c2048c5 100644 --- a/uv.lock +++ b/uv.lock @@ -569,7 +569,7 @@ wheels = [ [[package]] name = "kicoil" -version = "0.9.0" +version = "0.10.0" source = { editable = "." } dependencies = [ { name = "beautifulsoup4" },