117 lines
3.1 KiB
Python
117 lines
3.1 KiB
Python
#!/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()
|
|
|