Parametric parts for boxes with rounded corners
This commit is contained in:
parent
870b18db43
commit
3376457d5e
145
boxes.py
145
boxes.py
|
@ -10,6 +10,7 @@ class Boxes:
|
||||||
self.thickness = thickness
|
self.thickness = thickness
|
||||||
self.burn = 0.1
|
self.burn = 0.1
|
||||||
self.fingerJointSettings = (10.0, 10.0)
|
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.doveTailJointSettings = (10, 5, 50, 0.4) # width, depth, angle, radius
|
||||||
self.flexSettings = (1.5, 3.0, 15.0) # line distance, connects, width
|
self.flexSettings = (1.5, 3.0, 15.0) # line distance, connects, width
|
||||||
self.output = "box.svg"
|
self.output = "box.svg"
|
||||||
|
@ -29,6 +30,24 @@ class Boxes:
|
||||||
ctx.set_line_width(0.1)
|
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
|
### Turtle graphics commands
|
||||||
############################################################
|
############################################################
|
||||||
|
@ -202,14 +221,93 @@ class Boxes:
|
||||||
self.ctx.translate(*self.ctx.get_current_point())
|
self.ctx.translate(*self.ctx.get_current_point())
|
||||||
self.ctx.rotate(angle)
|
self.ctx.rotate(angle)
|
||||||
|
|
||||||
|
# Building blocks
|
||||||
|
|
||||||
def fingerHolesAt(self, x, y, length, angle=90, burn=None):
|
def fingerHolesAt(self, x, y, length, angle=90, burn=None):
|
||||||
if burn is None:
|
if burn is None:
|
||||||
burn = self.burn
|
burn = self.burn
|
||||||
|
# XXX burn with callbacks
|
||||||
self.ctx.save()
|
self.ctx.save()
|
||||||
self.moveTo(x, y+burn, angle)
|
self.moveTo(x, y+burn, angle)
|
||||||
self.fingerHoles(length)
|
self.fingerHoles(length)
|
||||||
self.ctx.restore()
|
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
|
### Parts
|
||||||
####################################################################
|
####################################################################
|
||||||
|
@ -245,46 +343,13 @@ class Boxes:
|
||||||
self.ctx.restore()
|
self.ctx.restore()
|
||||||
|
|
||||||
def wall(self, x=100, y=100, h=100, r=0):
|
def wall(self, x=100, y=100, h=100, r=0):
|
||||||
self.ctx.save()
|
self.surroundingWall(x,y,r,h, bottom='finger', callback={
|
||||||
dh = self.thickness + 5
|
0 : lambda: self.fingerHolesAt(x/6.0, 0, h),
|
||||||
self.moveTo(10, 0)
|
4 : lambda: self.fingerHolesAt(x/3.0-r, 0, h),
|
||||||
c4 = (r+self.burn)*math.pi*0.5 # circumference of quarter circle
|
1 : lambda: self.fingerHolesAt(y/2.0-r, 0, h),
|
||||||
|
3 : lambda: self.fingerHolesAt(y/2.0-r, 0, h),
|
||||||
self.fingerHolesAt(x/6.0, dh, h-dh)
|
2 : lambda: self.fingerHolesAt(x/2.0-r, 0, h),
|
||||||
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()
|
|
||||||
|
|
||||||
def smallWall(self, y, h):
|
def smallWall(self, y, h):
|
||||||
l = 0.5*y - self.thickness
|
l = 0.5*y - self.thickness
|
||||||
|
|
Loading…
Reference in New Issue