def circle(x0, y0, r):
part = "(((X-x0)**2 + (Y-y0)**2) <= r**2)"
part = replace(part,'x0',str(x0))
part = replace(part,'y0',str(y0))
part = replace(part,'r',str(r))
return part
def rectangle(x0, x1, y0, y1):
part = "((X >= x0) & (X <= x1) & (Y >= y0) & (Y <= y1))"
part = replace(part,'x0',str(x0))
part = replace(part,'x1',str(x1))
part = replace(part,'y0',str(y0))
part = replace(part,'y1',str(y1))
return part
def add(part1, part2):
part = "part1 | part2"
part = replace(part,'part1',part1)
part = replace(part,'part2',part2)
return part
def subtract(part1, part2):
part = "(part1) & ~(part2)"
part = replace(part,'part1',part1)
part = replace(part,'part2',part2)
return part
def move(part,dx,dy):
part = replace(part,'X','(X-'+str(dx)+')')
part = replace(part,'Y','(Y-'+str(dy)+')')
return part
def translate(part,dx,dy,dz):
part = replace(part,'X','(X-'+str(dx)+')')
part = replace(part,'Y','(Y-'+str(dy)+')')
part = replace(part,'Z','(Z-'+str(dz)+')')
return part
def rotate(part, angle):
angle = angle*pi/180
part = replace(part,'X','(cos(angle)*X+sin(angle)*y)')
part = replace(part,'Y','(-sin(angle)*X+cos(angle)*y)')
part = replace(part,'y','Y')
part = replace(part,'angle',str(angle))
return part
def rotate_90(part):
part = reflect_xy(part)
part = reflect_y(part)
return part
def rotate_180(part):
part = reflect_xy(part)
part = reflect_y(part)
part = reflect_xy(part)
part = reflect_y(part)
return part
def rotate_270(part):
part = reflect_xy(part)
part = reflect_y(part)
part = reflect_xy(part)
part = reflect_y(part)
part = reflect_xy(part)
part = reflect_y(part)
return part
def reflect_x(part):
part = replace(part,'X','-X')
return part
def reflect_y(part):
part = replace(part,'Y','-Y')
return part
def reflect_z(part):
part = replace(part,'Z','-Z')
return part
def reflect_xy(part):
part = replace(part,'X','temp')
part = replace(part,'Y','X')
part = replace(part,'temp','Y')
return part
def reflect_xz(part):
part = replace(part,'X','temp')
part = replace(part,'Z','X')
part = replace(part,'temp','Z')
return part
def reflect_yz(part):
part = replace(part,'Y','temp')
part = replace(part,'Z','Y')
part = replace(part,'temp','Z')
return part
cad.labels = []
class PCB:
def __init__(self,x0,y0,width,height,mask):
self.board = "False"
self.interior = rectangle(x0,x0+width,y0,y0+height)
self.exterior = subtract("True",rectangle(x0,x0+width,y0,y0+height))
self.mask = "False"
def add(self,part):
self.board = add(self.board,part)
self.mask = add(self.mask,move(part,-mask,mask))
self.mask = add(self.mask,move(part,-mask,-mask))
self.mask = add(self.mask,move(part,mask,mask))
self.mask = add(self.mask,move(part,mask,-mask))
return self
class part:
def add(self,pcb,x,y,z=0,angle=0):
self.x = x
self.y = y
self.z = z
self.angle = angle
if (angle == 90):
self.shape = rotate_90(self.shape)
elif (angle == 180):
self.shape = rotate_180(self.shape)
elif ((angle == 270) | (angle == -90)):
self.shape = rotate_270(self.shape)
angle = pi*angle/180
self.shape = translate(self.shape,x,y,z)
for i in range(len(self.pad)):
xnew = cos(angle)*self.pad[i].x + sin(angle)*self.pad[i].y
ynew = -sin(angle)*self.pad[i].x + cos(angle)*self.pad[i].y
self.pad[i].x = x + xnew
self.pad[i].y = y + ynew
self.pad[i].z += z
cad.labels.append(cad_text(x,y,z,self.value,size=14))
for i in range(len(self.labels)):
xnew = cos(angle)*self.labels[i].x + sin(angle)*self.labels[i].y
ynew = -sin(angle)*self.labels[i].x + cos(angle)*self.labels[i].y
self.labels[i].x = x + xnew
self.labels[i].y = y + ynew
self.labels[i].z += z
cad.labels.append(self.labels[i])
pcb = pcb.add(self.shape)
return pcb
def rotateToMatchVector(part,vecx,vecy):
length = sqrt(vecx*vecx + vecy*vecy)
if (length == 0):
return part
part = replace(part,'X','((COSANGLE)*X+(SINANGLE)*y)')
part = replace(part,'Y','(-(SINANGLE)*X+(COSANGLE)*y)')
part = replace(part,'y','Y')
part = replace(part,'COSANGLE',str(vecx/length))
part = replace(part,'SINANGLE',str(vecy/length))
return part
def lineWithThickness(x0,y0,x1,y1,w):
length = sqrt((y1-y0)*(y1-y0) + (x1-x0)*(x1-x0))
line = rectangle(0,length,-w/2,w/2)
line = rotateToMatchVector(line,x1-x0,y1-y0)
line = move(line,x0,y0)
return line
def getPointOnLine(point0,point1,distance):
x0 = point0.x
y0 = point0.y
z0 = point0.z
x1 = point1.x
y1 = point1.y
z1 = point1.z
length = sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0))
xdiff = x1-x0
ydiff = y1-y0
x = xdiff*distance/length
y = ydiff*distance/length
x = x + x0
y = y + y0
return point(x,y,z0)
def getPointInDirection(point0,angle,distance):
angle = positiveAngle(angle)
angle = angle*pi/180
x0 = point0.x
y0 = point0.y
z0 = point0.z
x = distance*cos(angle)
y = distance*sin(angle)
x = x + x0
y = y + y0
return point(x,y,z0)
def arc(centerX,centerY,innerRad,outerRad,startAngle,endAngle):
outer = circle(0,0,outerRad)
inner = circle(0,0,innerRad)
block1 = rectangle(-outerRad,outerRad,-outerRad,0)
block2 = rectangle(-outerRad,outerRad,0,outerRad)
block1 = rotate(block1,startAngle)
block2 = rotate(block2,endAngle)
part = subtract(outer,inner)
part = subtract(part,block1)
part = subtract(part,block2)
part = move(part,centerX,centerY)
return part
def positiveAngle(angle):
return (angle - 360 * floor(angle/360))
def polyline(width,cornerRadius,*points):
part = ""
previousEndPoint = None
previousLineAngle = None
for i in range(1,len(points)):
x0 = points[i-1].x
y0 = points[i-1].y
z0 = points[i-1].z
x1 = points[i].x
y1 = points[i].y
z1 = points[i].z
if (i==1):
omitFromStart = -width/2
else:
omitFromStart = cornerRadius + width/2
if (i == len(points)-1):
omitFromEnd = -width/2
else:
omitFromEnd = cornerRadius + width/2
startPoint = getPointOnLine(points[i-1],points[i],omitFromStart)
endPoint = getPointOnLine(points[i],points[i-1],omitFromEnd)
if (i==1):
part = lineWithThickness(startPoint.x,startPoint.y,endPoint.x,endPoint.y,width)
else:
part = add(part,lineWithThickness(startPoint.x,startPoint.y,endPoint.x,endPoint.y,width))
nextLineAngle = (math.atan2(y1-y0,x1-x0))*180/pi
if (previousLineAngle != None):
nextLineAngle = positiveAngle(nextLineAngle)
previousLineAngle = positiveAngle(previousLineAngle)
if (positiveAngle(nextLineAngle - previousLineAngle) < 180):
arcCenter = getPointInDirection(previousEndPoint,previousLineAngle+90,cornerRadius + width/2)
startAngle = previousLineAngle-90
endAngle = nextLineAngle-90
else:
arcCenter = getPointInDirection(previousEndPoint,previousLineAngle-90,cornerRadius + width/2)
startAngle = nextLineAngle+90
endAngle = previousLineAngle+90
part = add(part,arc(arcCenter.x,arcCenter.y,cornerRadius,cornerRadius+width,startAngle,endAngle))
previousLineAngle = nextLineAngle
previousEndPoint = endPoint
return part
def wire(pcb,width,*points):
newpoints = [points[0]]
for i in range(1,len(points)):
x0 = points[i-1].x
y0 = points[i-1].y
z0 = points[i-1].z
x1 = points[i].x
y1 = points[i].y
z1 = points[i].z
if (x0 != x1 and y0 != y1):
newpoints.append(point(x1,y0,z0))
newpoints.append(point(x1,y1,z0))
pcb.board = add(pcb.board,polyline(width,width,*newpoints))
return pcb
class letter(part):
def __init__(self,w,letter):
self.value = ''
self.pad = [point(0,0,0)]
self.labels = []
self.shape = ''
H = w*7
h = w*5
W = w*3
self.width = W+2*w
self.height = H+2*w
self.p0 = point(0, 0, 0)
self.p1 = point(w, 0, 0)
self.p2 = point(W, 0, 0)
self.p3 = point(W+w, 0, 0)
self.p4 = point(0, h-2*w, 0)
self.p5 = point(w, h-2*w, 0)
self.p6 = point(W, h-2*w, 0)
self.p7 = point(W+w, h-2*w, 0)
self.p8 = point(0, h, 0)
self.p9 = point(w, h, 0)
self.p10 = point(W, h, 0)
self.p11 = point(W+w, h, 0)
self.p12 = point(0, H, 0)
self.p13 = point(w, H, 0)
self.p14 = point(W, H, 0)
self.p15 = point(W+w, H, 0)
self.p16 = point(0, -2*w, 0)
self.p17 = point(w, -2*w, 0)
self.p18 = point(W, -2*w, 0)
self.p19 = point(W+w, -2*w, 0)
self.w2 = W
self.h2 = H
self.h1 = h
self.w1 = w
funcmap = { "a": self.a, "b": self.b, "c": self.c, "d": self.d,
"e": self.e, "f": self.f, "g": self.g, "h": self.h, "i":
self.i, "j": self.j, "k": self.k, "l": self.l, "m": self.m,
"n": self.n, "o": self.o, "p": self.p, "q": self.q, "r":
self.r, "s": self.s, "t": self.t, "u": self.u, "v": self.v,
"w": self.w, "x": self.x, "y": self.y, "z": self.z, " ":
self.space, "_": self.underscore, ".": self.dot, ",": self.comma}
funcmap.get(letter,self.errhandler)()
def errhandler(self):
self.underscore()
def space(self):
self.shape = 'False'
self.width = 2*self.w1
def underscore(self):
self.shape = polyline(self.w1, self.w1, self.p0, self.p2)
def dot(self):
self.shape = polyline(self.w1, self.w1, self.p0, self.p1)
def comma(self):
self.shape = polyline(self.w1, self.w1, self.p0, self.p1)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p1, self.p16))
def a(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p2, self.p3))
def b(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p12, self.p0))
def c(self):
self.shape = polyline(self.w1, self.w1, self.p6, self.p10, self.p8, self.p0, self.p2)
def d(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p14, self.p2, self.p3))
def e(self):
self.c()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p4, self.p6))
def f(self):
self.shape = polyline(self.w1, self.w1, self.p14, self.p13, self.p1)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p8, self.p10))
def g(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p18, self.p16))
def h(self):
self.shape = polyline(self.w1, self.w1, self.p12, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p8, self.p10, self.p2))
def i(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p0, self.p1)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p12, self.p12))
self.width = 3*self.w1
def j(self):
self.shape = polyline(self.w1, self.w1, self.p9, self.p17, self.p16)
self.width = 3*self.w1
def k(self):
self.shape = polyline(self.w1, self.w1, self.p12, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p4, self.p2))
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p4, self.p10))
def l(self):
self.shape = polyline(self.w1, self.w1, self.p12, self.p0, self.p1)
self.width = 3*self.w1
def m(self):
midhigh = point(2*self.w1, self.h1, 0)
midlow = point(2*self.w1, 0, 0)
self.shape = polyline(self.w1, self.w1, self.p8, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p8, midhigh, midlow))
self.shape = add(self.shape, polyline(self.w1, self.w1, midlow, midhigh, self.p11, self.p3))
self.width = self.width + self.w1
def n(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p8, self.p10, self.p2))
def o(self):
self.shape = polyline(self.w1,self.w1,self.p6,self.p10,self.p8,self.p0,self.p2,self.p6)
def p(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p8, self.p16))
def q(self):
self.o()
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p18, self.p19))
def r(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p8, self.p10, self.p6))
def s(self):
self.shape = polyline(self.w1, self.w1, self.p10, self.p8, self.p4, self.p6, self.p2, self.p0)
def t(self):
self.shape = polyline(self.w1, self.w1, self.p9, self.p1, self.p2)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p8, self.p10))
def u(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p0, self.p2, self.p10)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p2, self.p3))
def v(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p1)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p1, self.p6))
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p6, self.p10))
def w(self):
midhigh = point(2*self.w1, self.h1, 0)
self.shape = polyline(self.w1, self.w1, self.p8, self.p0)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, midhigh))
self.shape = add(self.shape, polyline(self.w1, self.w1, midhigh, self.p2))
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p2, self.p11))
self.width = self.width + self.w1
def x(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p2)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p10))
def y(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p1, self.p2)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p18, self.p17))
def z(self):
self.shape = polyline(self.w1, self.w1, self.p8, self.p10)
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p10, self.p0))
self.shape = add(self.shape, polyline(self.w1, self.w1, self.p0, self.p2))
class word(part):
def __init__(self,w,wordstring):
self.value = ''
self.pad = [point(0,0,0)]
self.labels = []
self.shape = 'False'
offsetX = 0
maxheight = 0
for character in wordstring:
letterObject = letter(w, character)
letterObject.shape = move(letterObject.shape,offsetX,0)
self.shape = add(self.shape, letterObject.shape)
offsetX = offsetX + letterObject.width
if letterObject.height > maxheight:
maxheight = letterObject.height
self.width = offsetX
self.height = maxheight
x0 = 1
y0 = 1
width = 1.4
height = .74
z = -.005
w = .018
mask = .004
pcb = PCB(x0,y0,width,height,mask)
WORD1 = word(w,'abcdefghijk')
WORD2 = word(w,'lmnopqrstuv')
WORD3 = word(w,'wxyz _.,')
pcb = WORD1.add(pcb,x0+w*2,y0+0.55,z)
pcb = WORD2.add(pcb,WORD1.x,WORD1.y-WORD1.height,z)
pcb = WORD3.add(pcb,WORD2.x,WORD2.y-WORD2.height,z)
cad.function = add(pcb.board,pcb.exterior)
d = 0.05
cad.xmin = x0-d cad.xmax = x0+width+d cad.ymin = y0-d cad.ymax = y0+height+d cad.zmin = z
cad.zmax = .050
dpi = 500 nxy = int(dpi*(cad.xmax-cad.xmin))
cad.nx = int(dpi*(cad.xmax-cad.xmin)) cad.ny = int(dpi*(cad.ymax-cad.ymin)) cad.nz = 1
cad.inches_per_unit = 1.0 cad.view('xy')