Skip to content

Instantly share code, notes, and snippets.

@tywtyw2002
Created December 14, 2021 04:37
Show Gist options
  • Save tywtyw2002/1a92a18576c852064f5b6cb7efb07200 to your computer and use it in GitHub Desktop.
Save tywtyw2002/1a92a18576c852064f5b6cb7efb07200 to your computer and use it in GitHub Desktop.
# KiCAD Hilbert Curve Gen
# Track Section Length in MM
track_section_length = 1.72
# Track width in MM
track_section_width = 1.17
# Hilbert Curve width / hight
g_w = 32
g_h = 64
def gilbert2d(width, height):
"""
# https://github.com/jakubcerveny/gilbert
Generalized Hilbert ('gilbert') space-filling curve for arbitrary-sized
2D rectangular grids. Generates discrete 2D coordinates to fill a rectangle
of size (width x height).
"""
if width >= height:
yield from generate2d(0, 0, width, 0, 0, height)
else:
yield from generate2d(0, 0, 0, height, width, 0)
def sgn(x):
return -1 if x < 0 else (1 if x > 0 else 0)
def generate2d(x, y, ax, ay, bx, by):
w = abs(ax + ay)
h = abs(bx + by)
(dax, day) = (sgn(ax), sgn(ay)) # unit major direction
(dbx, dby) = (sgn(bx), sgn(by)) # unit orthogonal direction
if h == 1:
# trivial row fill
for i in range(0, w):
yield(x, y)
(x, y) = (x + dax, y + day)
return
if w == 1:
# trivial column fill
for i in range(0, h):
yield(x, y)
(x, y) = (x + dbx, y + dby)
return
(ax2, ay2) = (ax//2, ay//2)
(bx2, by2) = (bx//2, by//2)
w2 = abs(ax2 + ay2)
h2 = abs(bx2 + by2)
if 2*w > 3*h:
if (w2 % 2) and (w > 2):
# prefer even steps
(ax2, ay2) = (ax2 + dax, ay2 + day)
# long case: split in two parts only
yield from generate2d(x, y, ax2, ay2, bx, by)
yield from generate2d(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by)
else:
if (h2 % 2) and (h > 2):
# prefer even steps
(bx2, by2) = (bx2 + dbx, by2 + dby)
# standard case: one step up, one long horizontal, one step down
yield from generate2d(x, y, bx2, by2, ax2, ay2)
yield from generate2d(x+bx2, y+by2, ax, ay, bx-bx2, by-by2)
yield from generate2d(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
-bx2, -by2, -(ax-ax2), -(ay-ay2))
board = pcbnew.GetBoard()
gen = gilbert2d(g_w, g_h)
last = None
for point in gen:
if last is not None:
t = pcbnew.PCB_TRACK(board)
st = pcbnew.wxPointMM(track_section_length * last[0], track_section_length * last[1])
t.SetStart(st)
et = pcbnew.wxPointMM(track_section_length * point[0], track_section_length * point[1])
t.SetEnd(et)
t.SetWidth(int(track_section_width * 1000000))
board.Add(t)
last = point
pcbnew.Refresh()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment