#!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "gerbonara", # "click" # ] # /// import math from gerbonara.cad.kicad.footprints import Atom, AtPos, XYCoord, Pad, Line, Arc, Stroke, Drill, Footprint, Polygon,\ FootprintInstance, Zone, Hatch, ZoneKeepout, ZonePolygon from gerbonara.layers import LayerStack import click __version__ = '1.0' def arc(a1, a2, r, fn=64): n = math.ceil(abs(a2 - a1) / (2*math.pi) * fn) for i in range(n+1): a = a1 + (a2 - a1) * i / n yield r * math.sin(a), r * math.cos(a) def segment(r1, r2, a1, a2, off1=0, off2=0, fn=64): a1_r2 = a1 + math.asin(off1 / r2) a1_r1 = a1 + math.asin(off1 / r1) a2_r2 = a2 - math.asin(off1 / r2) a2_r1 = a2 - math.asin(off1 / r1) yield from arc(a1_r2, a2_r2, r2, fn=fn) yield from arc(a2_r1, a1_r1, r1, fn=fn) @click.command() def cli(): footprint = Footprint( name='radial-pattern-001', generator=Atom('radial-pattern-gen'), generator_version=__version__, layer='F.Cu', descr=f"Radial pattern footprint", zone_connect=0) slot = 2.0 def make_ring(r1, r2, layer='F.Cu', fn=64): poly = Polygon(layer=layer, fill=Atom.solid, pts=[XYCoord(*xy) for xy in segment(r1, r2, 0, 2*math.pi, slot/2, slot/2, fn=fn)]) footprint.polygons.append(poly) r4 = 25 r3 = r4 - 5 outer_area = math.pi * (r4**2 - r3**2) gap = 2 r2 = r3 - gap r1 = math.sqrt(r2**2 - outer_area / math.pi) shield_w = 1 r5 = r4 + gap r6 = r5 + shield_w r0 = r1 - gap ri = r0 - shield_w pad_dia = 1 pad_off = slot/2 + pad_dia/2 for num, (r1, r2) in { '4': (r6, r5), '3': (r4, r3), '2': (r2, r1), '1': (r0, ri)}.items(): make_ring(r1, r2, fn=128) pad_r = (r1 + r2) / 2 pad_a = math.asin(pad_off / pad_r) footprint.pads.append(Pad( number=num, type=Atom.smd, shape=Atom.circle, at=AtPos(x=pad_r*math.sin(pad_a), y=pad_r*math.cos(pad_a)), size=XYCoord(x=pad_dia, y=pad_dia), layers=['F.Cu'])) h_dia = 8 footprint.pads.append(Pad( number='NC', type=Atom.np_thru_hole, shape=Atom.circle, at=AtPos(x=0, y=0), size=XYCoord(x=h_dia, y=h_dia), drill=Drill(diameter=h_dia), layers=['F.Cu'])) pts = [XYCoord(-slot/2, 0), XYCoord(slot/2, 0), XYCoord(slot/2, r6 + gap), XYCoord(-slot/2, r6 + gap)] footprint.zones.append(Zone(layers=['*.Cu'], hatch=Hatch(), filled_areas_thickness=False, keepout=ZoneKeepout(copperpour_allowed=False), polygon=ZonePolygon(pts=pts))) footprint.write('footprints.pretty/radial-pattern-001.kicad_mod') #stack = LayerStack() #FootprintInstance(0, 0, footprint).render(stack) #with open('test.svg', 'w') as f: # f.write(stack.to_pretty_svg()) if __name__ == '__main__': cli()