Parametric parts for boxes with rounded corners

This commit is contained in:
Florian Festi 2013-04-16 11:27:48 +09:00
parent 870b18db43
commit 3376457d5e
1 changed files with 106 additions and 41 deletions

147
boxes.py
View File

@ -10,6 +10,7 @@ class Boxes:
self.thickness = thickness
self.burn = 0.1
self.fingerJointSettings = (10.0, 10.0)
self.fingerHoleEdgeWidth = 1.0 # multitudes of self.thickness
self.doveTailJointSettings = (10, 5, 50, 0.4) # width, depth, angle, radius
self.flexSettings = (1.5, 3.0, 15.0) # line distance, connects, width
self.output = "box.svg"
@ -29,6 +30,24 @@ class Boxes:
ctx.set_line_width(0.1)
def cc(self, callback, number, x=0.0, y=0.0):
"""call callback"""
self.ctx.save()
self.moveTo(x, y)
if callable(callback):
callback(number)
elif hasattr(callback, '__getitem__'):
try:
callback = callback[number]
if callable(callback):
callback()
except KeyError:
pass
except:
self.ctx.restore()
raise
self.ctx.restore()
############################################################
### Turtle graphics commands
############################################################
@ -202,14 +221,93 @@ class Boxes:
self.ctx.translate(*self.ctx.get_current_point())
self.ctx.rotate(angle)
# Building blocks
def fingerHolesAt(self, x, y, length, angle=90, burn=None):
if burn is None:
burn = self.burn
# XXX burn with callbacks
self.ctx.save()
self.moveTo(x, y+burn, angle)
self.fingerHoles(length)
self.ctx.restore()
def roundedPlate(self, x, y, r, callback=None):
"""fits surroundingWall
first edge is split to have a joint in the middle of the side
callback is called at the beginning of the straight edges
0, 1 for the two part of the first edge, 2, 3, 4 for the others"""
self.ctx.save()
self.moveTo(r, 0)
self.cc(callback, 0)
self.fingerJoint(x/2.0-r)
self.cc(callback, 1)
self.fingerJoint(x/2.0-r)
for i, l in zip(range(3), (y, x, y)):
self.corner(90, r)
self.cc(callback, i+2)
self.fingerJoint(l-2*r)
self.corner(90, r)
self.ctx.restore()
def _edge(self, l, style):
if style == 'edge':
self.edge(l)
elif style == 'holes':
self.fingerHoleEdge(l, 5)
elif style == 'finger':
self.fingerJoint(l, positive=False)
def _edgewidth(self, style):
if style == 'holes':
return (self.fingerHoleEdgeWidth+1) * self.thickness
elif style == 'finger':
return self.thickness
return 0.0
def surroundingWall(self, x, y, r, h,
bottom='edge', top='edge',
callback=None):
"""
h : inner height, not counting the joints
callback is called a beginn of the flat sides with
0 for right half of first x side;
1 and 3 for y sides;
2 for second x side
4 for second half of thefirst x side
"""
c4 = (r+self.burn)*math.pi*0.5 # circumference of quarter circle
topwidth = self._edgewidth(top)
bottomwidth = self._edgewidth(bottom)
self.cc(callback, 0, y=bottomwidth+self.burn)
self._edge(x/2.0-r, bottom)
for i, l in zip(range(4), (y, x, y, 0)):
self.flex(c4, h+topwidth+bottomwidth)
self.cc(callback, i+1, y=bottomwidth+self.burn)
if i < 3:
self._edge(l-2*r, bottom)
self._edge(x/2.0-r, bottom)
self.corner(90)
self.edge(bottomwidth)
self.doveTailJoint(h)
self.edge(topwidth)
self.corner(90)
self._edge(x/2.0-r, top)
for i, l in zip(range(4), (y, x, y, 0)):
self.edge(c4)
if i < 3:
self._edge(l - 2*r, top)
self._edge(x/2.0-r, top)
self.corner(90)
self.edge(topwidth)
self.doveTailJoint(h, positive=False)
self.edge(bottomwidth)
self.corner(90)
####################################################################
### Parts
####################################################################
@ -245,46 +343,13 @@ class Boxes:
self.ctx.restore()
def wall(self, x=100, y=100, h=100, r=0):
self.ctx.save()
dh = self.thickness + 5
self.moveTo(10, 0)
c4 = (r+self.burn)*math.pi*0.5 # circumference of quarter circle
self.fingerHolesAt(x/6.0, dh, h-dh)
self.fingerHoleEdge(0.5*x-r, 5)
self.flex(c4, h)
self.fingerHolesAt(y/2.0-r, dh, h-dh)
self.fingerHoleEdge(y-2*r, 5)
self.flex(c4, h)
self.fingerHolesAt(x/2.0-r, dh, h-dh)
self.fingerHoleEdge(x-2*r, 5)
self.flex(c4, h)
self.fingerHolesAt(y/2.0-r, dh, h-dh)
self.fingerHoleEdge(y-2*r, 5)
self.flex(c4, h)
self.fingerHolesAt(x/3.0-r, dh, h-dh)
self.fingerHoleEdge(0.5*x-r, 5)
self.corner(90)
self.edge(dh)
self.doveTailJoint(h-dh, positive=False)
self.corner(90)
self.edge(2*(x+y-4*r)+4*c4)
self.corner(90)
self.doveTailJoint(h-dh)
self.edge(dh)
self.corner(90)
self.ctx.restore()
self.surroundingWall(x,y,r,h, bottom='finger', callback={
0 : lambda: self.fingerHolesAt(x/6.0, 0, h),
4 : lambda: self.fingerHolesAt(x/3.0-r, 0, h),
1 : lambda: self.fingerHolesAt(y/2.0-r, 0, h),
3 : lambda: self.fingerHolesAt(y/2.0-r, 0, h),
2 : lambda: self.fingerHolesAt(x/2.0-r, 0, h),
})
def smallWall(self, y, h):
l = 0.5*y - self.thickness
@ -370,7 +435,7 @@ class Boxes:
self.basePlate(x, y, r)
self.ctx.restore()
self.ctx.stroke()
self.surface.flush()