Any comment, suggestion, improvements to make it more realistic welcome !
Code: Select all
Size = 20
CF::MaxNatural = 2^50
CF::Background = [ b -1 ]
hole = 0.5 // hole radius
diam = 1.7 // pad radius
width = 1 // track width
height = 4
spacing = height*1.9
turnoffset = sqrt(2)/2
probroundpad = 45 // probability of round pad vs square pad (%)
probturn45 = 60 // probability of 45° turn vs 90° turn (%)
DEBUG = 0
startshape PCB
shape PCB {
if (DEBUG) {
segment [y -(height*2) h 20 a 0 sat 1]
turn45 [y (height*1) x (height)]
turn45 []
roundpad [ x (height*3) y (height) r 90]
}
else
Rows(0, Size) []
}
shape Rows(natural top, natural n) {
middle = bitand(randint(2^Size), bitnot(1))
bottom = if(n, randint(2^Size), 0)
Row(top,middle,bottom,Size) [ ]
if (n)
Rows(bottom, n--1) [ y -spacing ]
}
shape Row(natural top, natural middle, natural bottom, natural expo) {
Cell(bitand(middle,1), bitand(top,1),
bitand(middle,2), bitand(bottom,1)) []
if (expo)
Row(div(top,2), div(middle,2), div(bottom,2), expo--1) [ x spacing ]
}
shape Cell(natural left, natural top, natural right, natural bottom) {
if (top && bottom && !left && !right)
segment []
if (!top && !bottom && left && right)
segment [ r 90 ]
if (bottom && right)
turn [ ]
if (right && top)
turn [ r 90 ]
if (top && left)
turn [ r 180 ]
if (left && bottom)
turn [ r 270 ]
if (left && !top && !right && !bottom)
pad [ r 90 ]
if (!left && top && !right && !bottom)
pad [ ]
if (!left && !top && right && !bottom)
pad [ r 270 ]
if (!left && !top && !right && bottom)
pad [ r 180 ]
}
shape pad {
if (randint(100) >= probroundpad)
roundpad []
else
squarepad []
}
shape turn {
if (randint(100) >= probturn45)
turn90 []
else
turn45 []
}
path segment { // straight segment, x 1, y 4
MOVETO(-width/2,-height)
LINETO(-width/2,height)
LINETO(width/2,height)
LINETO(width/2,-height)
FILL()[b 1]
}
path turn45 {
ss = sqrt(2)/2
ss = 0.999
offs = width - width*sqrt(2)/2
MOVETO(-width/2,-height)
LINETO(-width/2,-width+offs-turnoffset)
LINETO(width-offs+turnoffset,width/2)
LINETO(height,width/2)
LINETO(height,-width/2)
LINETO(width+offs+turnoffset,-width/2)
LINETO(width/2,-width-offs-turnoffset)
LINETO(width/2,-height)
CLOSEPOLY()
FILL[b 1]
}
path turn90 {
MOVETO(-width/2, -height) // origin
LINETO(-width/2,width/2) // A
LINETO(height,width/2) // B
LINETO(height,-width/2) // C
LINETO(width/2,-width/2) // D
LINETO(width/2,-height)
CLOSEPOLY()
FILL[b 1]
}
path squarepad {
MOVETO(-width/2, height)
LINETO(-width/2,diam)
LINETO(-diam,diam)
LINETO(-diam,-diam)
LINETO(diam,-diam)
LINETO(diam,diam)
LINETO(width/2,diam)
LINETO(width/2, height)
MOVETO(0, hole)
ARCTO(0, -hole, -hole)
ARCTO(0, hole, -hole)
FILL()[b 1]
}
path roundpad {
overlap = (diam-hole/2) // the track slightly overlap the pad
MOVETO(0, diam)
ARCTO(0, -diam,diam)
ARCTO(0, diam, diam)
LINETO(0, height)
MOVETO(0, hole)
ARCTO(0, -hole, -hole)
ARCTO(0, hole, -hole)
FILL()[b 1]
MOVETO(-width/2, height)
LINETO(width/2, height)
LINETO(width/2, overlap)
LINETO(-width/2,overlap)
FILL()[b 1]
}