diff --git a/battery-case-generator.py b/battery-case-generator.py index 6063b04..5eba2c9 100755 --- a/battery-case-generator.py +++ b/battery-case-generator.py @@ -13,11 +13,13 @@ parser.add_argument('--kerf', default=.1, type=float, help='Kerf') parser.add_argument('--corner-length', default=4, help='Length of stretch corner in material thicknesses') parser.add_argument('--stretch', default=1.05, type=float, help='Reduction factor of stretch material') parser.add_argument('--horizontal-finger', default=5.0, type=float, help='Width of horizontal fingers') -parser.add_argument('--vertical-finger', default=5.0, type=float, help='Width of vertical fingers') +parser.add_argument('--vertical-finger', default=15.0, type=float, help='Width of vertical fingers') parser.add_argument('--padding', default=1.5, type=float, help='Padding around holes') -parser.add_argument('--outside-padding', default=4, type=float, help='Extra padding between holes and wall') +parser.add_argument('--outside-padding', default=4.0, type=float, help='Extra padding between holes and wall') +parser.add_argument('--extra-height', default=2.0, type=float, help='Extra vertical space') parser.add_argument('--thickness', default=3.0, type=float, help='Thickness of material') parser.add_argument('--lid', default=0.2, type=float, help='How much extra play to give the lid') +parser.add_argument('--tooth', default=0.8, type=float, help='How much to round the edges of the teeth') parser.add_argument('--verbose', action='store_true', help='Print computed parameter values') args = parser.parse_args() assert (args.dimension % 2) == 1 @@ -54,17 +56,18 @@ args.interior_leg = (args.interior_edge-args.horizontal_finger-args.kerf)/2-arg finger_length = args.interior_edge-2.0*args.corner_inset args.n_hor_fingers = max(int(finger_length/args.horizontal_finger/2), 1) args.exterior_leg = (finger_length-(2*args.n_hor_fingers-1)*args.horizontal_finger+args.kerf)/2 -args.exterior_slot = (args.exterior_edge-args.horizontal_finger+args.kerf)/2 -args.n_ver_fingers = int(args.height/args.vertical_finger/2) -args.vertical_finger = args.height/args.n_ver_fingers/2 -args.slots = [args.vertical_finger*2.5-args.thickness*0.5, args.vertical_finger*4.5-args.thickness*0.5] +args.wall_leg = (args.interior_edge-args.corner-(2*args.n_hor_fingers-1)*args.horizontal_finger+args.kerf)/2 +args.exterior_slot = (args.interior_edge-args.horizontal_finger+args.kerf)/2 +args.n_ver_fingers = int((args.height+args.extra_height)/args.vertical_finger) +top_slot = args.extra_height+0.5*args.height +args.slots = [top_slot, top_slot+2*args.thickness] if args.verbose: print(args, file=sys.stderr) BOX = 2.0*args.exterior_edge+5.0 DIMX = 3.0*BOX -DIMY = 2.0*BOX+args.height+3.0*args.thickness +DIMY = 2.0*BOX+args.height+args.extra_height+2.0*args.thickness+5.0 PI3 = math.pi/3 HOLES = '' @@ -171,119 +174,111 @@ def draw_plane(cx, cy, layer): turtle.circle(args.corner_radius, 60) HOLES += '\n' % turtle.to_s() -def draw_side(x0, y0, h, slots): - global HOLES, SHAPES - turtle = svgturtle.SvgTurtle(x0, y0+args.thickness) - for finger in range(args.n_hor_fingers): - turtle.forward(args.exterior_leg-args.kerf if finger == 0 else args.horizontal_finger-args.kerf) +def draw_flex(t, h): + global HOLES + turtle = svgturtle.SvgTurtle(t.x, t.y) + al = h/3.0-args.thickness + bl = (h-args.thickness)/3.0-args.thickness + nx = int(args.corner_length) + dx = args.corner/(2*nx-1) + for stripe in range(nx): + turtle.right(90) + turtle.forward(0.5*al) + turtle.penup() + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(al) + turtle.penup() + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(al) + turtle.penup() + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(0.5*al) + turtle.penup() + turtle.left(90) + turtle.forward(dx) + turtle.left(90) + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(bl) + turtle.penup() + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(bl) + turtle.penup() + turtle.forward(args.thickness) + turtle.pendown() + turtle.forward(bl) + turtle.penup() + turtle.forward(args.thickness) + turtle.right(90) + turtle.forward(dx) + turtle.pendown() + HOLES += '\n' % turtle.to_s() + +def draw_case_h(turtle, h, top): + turtle.forward(0.5*args.interior_edge-0.5*args.corner) + for side in range(6): turtle.left(90) turtle.forward(args.thickness) turtle.right(90) - turtle.forward(args.horizontal_finger+args.kerf) + if top: + draw_flex(turtle, h+2*args.thickness) + turtle.forward(args.corner) turtle.right(90) turtle.forward(args.thickness) turtle.left(90) - turtle.forward(args.exterior_leg-args.kerf-args.thickness) - turtle.right(90) - for finger in range(args.n_ver_fingers): - turtle.forward(args.vertical_finger-(args.kerf/2 if finger==0 else args.kerf)) - turtle.left(90) - turtle.forward(args.thickness) - turtle.right(90) - turtle.forward(args.vertical_finger+args.kerf) - turtle.right(90) - if finger < args.n_ver_fingers-1: + if side == 5: + break + turtle.forward(args.wall_leg-0.5*args.kerf) + for finger in range(args.n_hor_fingers): + if finger > 0: + turtle.forward(args.horizontal_finger-args.kerf) + turtle.left(90) + turtle.forward(args.thickness) + turtle.right(90) + turtle.forward(args.horizontal_finger+args.kerf) + turtle.right(90) turtle.forward(args.thickness) turtle.left(90) - turtle.forward(args.exterior_edge-args.thickness) - turtle.right(90) + turtle.forward(args.wall_leg-0.5*args.kerf) + turtle.forward(0.5*args.interior_edge-0.5*args.corner) + +def draw_case_v(turtle, h): + ey = turtle.y+h + leg = (h-(args.n_ver_fingers-0.66)*args.vertical_finger)/2.0 + slope = args.vertical_finger/math.sqrt(18) + turtle.forward(leg) for finger in range(args.n_ver_fingers): - turtle.forward(args.vertical_finger-(args.kerf/2 if finger==0 else args.kerf)) - turtle.left(90) - turtle.forward(args.thickness) - turtle.right(90) - turtle.forward(args.vertical_finger+args.kerf) - turtle.right(90) - if finger < args.n_ver_fingers-1: - turtle.forward(args.thickness) - turtle.left(90) - SHAPES += '\n' % turtle.to_s() - for slot in slots: - x = x0+args.exterior_slot - y = y0+slot - w = args.horizontal_finger-args.kerf - h = args.thickness-args.kerf - HOLES += '\n' % (x, y, w, h) + ty = ey if finger==args.n_ver_fingers-1 else turtle.y+args.vertical_finger + turtle.circle(args.tooth, 135) + turtle.forward(slope) + turtle.circle(-args.tooth, 135) + turtle.forward(0.66*args.vertical_finger) + turtle.circle(-args.tooth, 135) + turtle.forward(slope) + turtle.circle(args.tooth, 135) + turtle.forward(ty-turtle.y) def draw_case(x0, y0, h, slots): global HOLES, SHAPES - turtle = svgturtle.SvgTurtle(x0, y0) - turtle.forward(args.exterior_edge*0.5) - for side in range(6): - turtle.right(90) - turtle.forward(args.height-args.thickness) - turtle.penup() - turtle.back(args.height-args.thickness) - turtle.left(90) - turtle.forward(2*args.thickness) - turtle.right(90) - turtle.pendown() - turtle.forward(args.height-args.thickness) - turtle.penup() - turtle.back(args.height-args.thickness) - turtle.left(90) - turtle.pendown() - if side==5: - break - turtle.forward(args.exterior_edge-args.thickness*2) - turtle.forward(args.exterior_edge*0.5-args.thickness*2) + turtle = svgturtle.SvgTurtle(x0, y0+args.thickness) + draw_case_h(turtle, h, True) turtle.right(90) - for finger in range(args.n_ver_fingers): - turtle.forward(args.vertical_finger-(args.kerf/2 if finger==0 else args.kerf)) - turtle.left(90) - turtle.forward(args.thickness) - turtle.right(90) - turtle.forward(args.vertical_finger+args.kerf) - turtle.right(90) - if finger < args.n_ver_fingers-1: - turtle.forward(args.thickness) - turtle.left(90) - turtle.forward(args.exterior_edge*0.5) - for side in range(6): - turtle.right(90) - turtle.forward(args.height-args.thickness) - turtle.penup() - turtle.back(args.height-args.thickness) - turtle.left(90) - turtle.pendown() - if side==5: - break - for finger in range(args.n_hor_fingers): - turtle.forward(args.exterior_leg if finger == 0 else args.horizontal_finger+args.kerf) - turtle.left(90) - turtle.forward(args.thickness) - turtle.right(90) - turtle.forward(args.horizontal_finger-args.kerf) - turtle.right(90) - turtle.forward(args.thickness) - turtle.left(90) - turtle.forward(args.exterior_leg) - turtle.forward(args.exterior_edge*0.5) + draw_case_v(turtle, h) turtle.right(90) - for finger in range(args.n_ver_fingers): - turtle.forward(args.vertical_finger-(args.kerf/2 if finger==0 else args.kerf)) - turtle.left(90) - turtle.forward(args.thickness) - turtle.right(90) - turtle.forward(args.vertical_finger+args.kerf) - turtle.right(90) - if finger < args.n_ver_fingers-1: - turtle.forward(args.thickness) - turtle.left(90) + draw_case_h(turtle, h, False) + turtle.penup() + turtle.left(90) + turtle.back(h) + turtle.pendown() + draw_case_v(turtle, h) SHAPES += '\n' % turtle.to_s() for slot in slots: for side in range(5): - x = x0+(side+0.5)*args.exterior_edge+args.thickness+args.exterior_slot + x = x0+(side+.5)*args.interior_edge+args.exterior_slot y = y0+slot w = args.horizontal_finger-args.kerf h = args.thickness-args.kerf @@ -299,6 +294,6 @@ draw_plane(1.5*BOX, 1.5*BOX, 'rim') draw_plane(1.5*BOX, 1.5*BOX, 'plug') draw_plane(2.5*BOX, 1.5*BOX, 'lid') draw_plane(2.5*BOX, 1.5*BOX, 'plug_mark') -draw_case(0.05*args.grid*args.dimension, 2.0*BOX, args.height, args.slots) +draw_case(0.05*args.grid*args.dimension, 2.0*BOX, args.height+args.extra_height, args.slots) print('', HOLES, '', '', MARKS, '', '', SHAPES, '', sep='\n') print('')