diff --git a/boxes.py b/boxes.py index f5b7389..45d788d 100755 --- a/boxes.py +++ b/boxes.py @@ -10,13 +10,14 @@ class Boxes: self.thickness = thickness self.burn = 0.1 self.fingerJointSettings = (10.0, 10.0) + self.doveTailJointSettings = (15, 10, 60, 2) # width, depth, angle, radius self.flexSettings = (1.5, 3.0, 15.0) # line distance, connects, width self.output = "box.svg" self._init_surface() def _init_surface(self): - width = 300 - height = 200 + width = 700 + height = 400 self.surface = cairo.SVGSurface(self.output, width, height) self.ctx = ctx = cairo.Context(self.surface) @@ -45,7 +46,7 @@ class Boxes: self.ctx.arc_negative(0, -(radius+self.burn), radius+self.burn, 0.5*math.pi, rad + 0.5*math.pi) - self.continueDirection(degrees) + self.continueDirection(rad) def edge(self, length): self.ctx.line_to(length, 0) @@ -96,6 +97,50 @@ class Boxes: self.ctx.line_to(length, 0) self.ctx.translate(*self.ctx.get_current_point()) + + # helpers for doveTailJoint + def _turnLeft(self, radius, angle): + self.ctx.arc(0, radius, radius, + -0.5*math.pi, angle) + self.continueDirection(0.5*math.pi+angle) + + def _turnRight(self, radius, angle): + self.ctx.arc_negative(0, -radius, radius, + 0.5*math.pi, -angle) + self.continueDirection(-0.5*math.pi - angle) + + def _turn(self, radius, angle, right=True): + if right: + self._turnRight(radius, angle) + else: + self._turnLeft(radius, angle) + + def doveTailJoint(self, length, positive=True, settings=None): + width, depth, angle, radius = settings or self.doveTailJointSettings + angle = math.pi*angle/180.0 + alpha = 0.5*math.pi - angle + + l1 = radius/math.tan(alpha/2.0) + diffx = 0.5*depth/math.tan(alpha) + l2 = 0.5*depth / math.sin(alpha) + + sections = int((length) // (width*2)) + leftover = length - sections*width*2 + + self.edge((width+leftover)/2.0+diffx-l1) + for i in xrange(sections): + self._turn(radius+self.burn, angle, right=positive) + self.edge(2*(l2-l1)) + self._turn(radius-self.burn, angle, right=not positive) + self.edge(2*(diffx-l1)+width) + self._turn(radius-self.burn, angle, right=not positive) + self.edge(2*(l2-l1)) + self._turn(radius+self.burn, angle, right=positive) + if i