@@ -52,6 +52,7 @@ args.corner_inset = args.corner_s*math.sqrt(3)/math.pi | |||
args.plug_inset = args.plug_radius/math.sqrt(3) | |||
args.interior_edge = args.grid*args.dimension*0.5+args.outside_padding | |||
args.plug_edge = args.interior_edge-args.thickness | |||
args.disc_radius = 0.45*(math.sqrt(3)-1)*args.plug_edge+args.plug_inset | |||
args.exterior_edge = args.interior_edge+2.0*args.thickness | |||
args.interior_leg = (args.interior_edge-args.horizontal_finger-args.kerf)/2-args.corner_inset | |||
finger_length = args.interior_edge-2.0*args.corner_inset | |||
@@ -84,16 +85,33 @@ def draw_grid(cx, cy): | |||
for col in range(num_col): | |||
HOLES += '<circle cx="%.2f" cy="%.2f" r="%.2f"/>\n' % (cxr+col*args.grid, cyr, args.radius) | |||
def draw_disc(cx, cy, layer): | |||
global HOLES, SHAPES, MARKS | |||
turtle = svgturtle.SvgTurtle(cx, cy) | |||
turtle.penup() | |||
turtle.forward(args.disc_radius) | |||
turtle.pendown() | |||
turtle.left(90) | |||
turtle.circle(args.disc_radius) | |||
turtle.penup() | |||
turtle.home() | |||
if layer=='disc': | |||
HOLES += '<path d="%s"/>\n' % turtle.to_s() | |||
else: | |||
MARKS += '<path d="%s"/>\n' % turtle.to_s() | |||
def draw_plane(cx, cy, layer): | |||
global HOLES, SHAPES, MARKS | |||
if layer=='interior': | |||
edge = args.interior_edge | |||
elif layer=='plug' or layer=='plug_mark': | |||
elif layer=='plug' or layer=='plug_mark' or layer=='opening': | |||
edge = args.plug_edge | |||
else: | |||
edge = args.exterior_edge | |||
turtle = svgturtle.SvgTurtle(cx, cy) | |||
turtle.penup() | |||
if layer=='plug_mark': | |||
turtle.right(30) | |||
turtle.forward(edge) | |||
turtle.right(120) | |||
if layer=='interior': | |||
@@ -113,6 +131,14 @@ def draw_plane(cx, cy, layer): | |||
turtle.forward(edge-2.0*args.corner_inset) | |||
turtle.circle(-args.corner_radius, 60) | |||
elif layer=='plug' or layer=='plug_mark': | |||
turtle.forward(args.plug_inset) | |||
turtle.pendown() | |||
for side in range(6): | |||
turtle.right(90) | |||
turtle.circle(0.5*edge-args.plug_inset, 180) | |||
turtle.right(90) | |||
turtle.circle(-args.plug_radius, 60) | |||
elif layer=='opening': | |||
turtle.forward(args.plug_inset) | |||
turtle.pendown() | |||
for side in range(6): | |||
@@ -292,9 +318,12 @@ draw_grid(1.5*BOX, 0.5*BOX) | |||
draw_plane(1.5*BOX, 0.5*BOX, 'interior') | |||
draw_plane(0.5*BOX, 1.5*BOX, 'bottom') | |||
draw_plane(1.5*BOX, 1.5*BOX, 'rim') | |||
draw_plane(1.5*BOX, 1.5*BOX, 'plug') | |||
draw_plane(1.5*BOX, 1.5*BOX, 'opening') | |||
draw_disc(1.5*BOX, 1.5*BOX, 'disc') | |||
draw_plane(2.5*BOX, 0.5*BOX, 'plug') | |||
draw_plane(2.5*BOX, 1.5*BOX, 'lid') | |||
draw_plane(2.5*BOX, 1.5*BOX, 'plug_mark') | |||
draw_disc(2.5*BOX, 1.5*BOX, 'disc_mark') | |||
draw_case(0.05*args.grid*args.dimension, 2.0*BOX, args.height+args.extra_height+args.thickness, args.slots) | |||
print('<g fill="none" stroke="black">', SHAPES, '</g>', '<g fill="none" stroke="red">', HOLES, '</g>', '<g fill="none" stroke="blue">', MARKS, '</g>', sep='\n') | |||
print('</svg>') |
@@ -53,22 +53,27 @@ class SvgTurtle(): | |||
self.left(w) | |||
self.right(w2) | |||
else: | |||
ra = extent*self.cvtangle | |||
h = self.heading-.5*ra if radius>0 else self.heading+.5*ra | |||
dx = abs(radius)*math.cos(h) | |||
dy = abs(radius)*math.sin(h) | |||
if extent>355: | |||
self.circle(radius, 355) | |||
extent -= 355 | |||
ra = self.cvtangle*(extent if radius < 0 else -extent) | |||
cx = self.x+radius*math.cos(self.heading-.5*math.pi) | |||
cy = self.y+radius*math.sin(self.heading-.5*math.pi) | |||
th = self.heading+.5*math.pi+ra | |||
dx = cx+radius*math.cos(th)-self.x | |||
dy = cy+radius*math.sin(th)-self.y | |||
lg = 1 if extent >= 180 else 0 | |||
sw = 0 if radius > 0 else 1 | |||
if self.pen: | |||
if self.path == '': | |||
self.path = "M %.2f,%.2f" % (self.x,self.y) | |||
self.path += " a %.2f %.2f %.2f %d %d %.2f %.2f" % (radius, radius, extent, lg, sw, dx, dy) | |||
elif self.path != '': | |||
self.path += " m %.2f, %.2f" % (dx, dy) | |||
self.x += dx | |||
self.y += dy | |||
if radius > 0: | |||
self.left(extent) | |||
else: | |||
self.right(extent) | |||
self.heading = (self.heading + ra) % math.tau | |||
def to_s(self): | |||
return self.path | |||
@@ -77,6 +82,8 @@ class SvgTurtle(): | |||
self.x = self.homex | |||
self.y = self.homey | |||
self.heading = 0 | |||
if self.path != '': | |||
self.path += " M %.2f, %.2f" % (self.x, self.y) | |||
def reset(self): | |||
self.path = '' | |||
@@ -0,0 +1,43 @@ | |||
#!/usr/bin/env python3 | |||
import svgturtle | |||
print('<svg viewBox="0 0 2000 2000" xmlns="http://www.w3.org/2000/svg">') | |||
turtle_tl = svgturtle.SvgTurtle(500, 750) | |||
turtle_tr = svgturtle.SvgTurtle(1500, 750) | |||
turtle_bl = svgturtle.SvgTurtle(500, 1000) | |||
turtle_br = svgturtle.SvgTurtle(1500, 1000) | |||
ANGLE=0 | |||
for i in range(7): | |||
turtle_tl.home() | |||
turtle_tl.left(ANGLE) | |||
turtle_tl.circle(110+i*50, (i+1)*45, 50) | |||
turtle_bl.home() | |||
turtle_bl.right(ANGLE) | |||
turtle_bl.circle(-(110+i*50), (i+1)*45, 50) | |||
turtle_tr.home() | |||
turtle_tr.right(ANGLE) | |||
turtle_tr.circle(140+i*50, (i+1)*45, 50) | |||
turtle_br.home() | |||
turtle_br.left(ANGLE) | |||
turtle_br.circle(-(140+i*50), (i+1)*45, 50) | |||
print('<path fill="none" stroke="black" d="%s %s %s %s"/>' % (turtle_tl.to_s(), turtle_tr.to_s(), turtle_bl.to_s(), turtle_br.to_s())) | |||
turtle_tl.reset() | |||
turtle_tr.reset() | |||
turtle_bl.reset() | |||
turtle_br.reset() | |||
for i in range(8): | |||
turtle_tl.home() | |||
turtle_tl.left(ANGLE) | |||
turtle_tl.circle(100+i*50, (i+1)*45) | |||
turtle_bl.home() | |||
turtle_bl.right(ANGLE) | |||
turtle_bl.circle(-(100+i*50), (i+1)*45) | |||
turtle_tr.home() | |||
turtle_tr.right(ANGLE) | |||
turtle_tr.circle(130+i*50, (i+1)*45) | |||
turtle_br.home() | |||
turtle_br.left(ANGLE) | |||
turtle_br.circle(-(130+i*50), (i+1)*45) | |||
print('<path fill="none" stroke="blue" d="%s %s %s %s"/>' % (turtle_tl.to_s(), turtle_tr.to_s(), turtle_bl.to_s(), turtle_br.to_s())) | |||
print('</svg>') |