diff --git a/battery-case-generator.py b/battery-case-generator.py
new file mode 100755
index 0000000..09ac24e
--- /dev/null
+++ b/battery-case-generator.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+
+import math
+import sys
+import argparse
+import svgturtle
+
+parser = argparse.ArgumentParser(description='Generate a hexagonal battery case')
+parser.add_argument('--dimension', default=5, type=int, help='Grid dimension')
+parser.add_argument('--height', type=float, help='Height of battery')
+parser.add_argument('--hole', default='AA', help='Hole diameter (mm or A, AA, AAA)')
+parser.add_argument('--kerf', default=.1, type=float, help='Kerf')
+parser.add_argument('--horizontal-finger', default=10.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('--padding', default=1.5, type=float, help='Padding around holes')
+parser.add_argument('--outside-padding', default=2, type=float, help='Extra padding between holes and wall')
+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')
+
+args = parser.parse_args()
+assert (args.dimension % 2) == 1
+
+BATTERY = {
+ 'AAA': [10.5, 44.5],
+ 'AA': [14.5, 50.5],
+ 'C': [26.2, 50.0],
+ 'D': [34.2, 61.5],
+}
+
+if args.hole in BATTERY:
+ dim = BATTERY[args.hole]
+ args.hole = dim[0]
+ if args.height == None:
+ args.height = dim[1]
+else:
+ args.hole = float(args.hole)
+ assert(args.height != None)
+
+GRID = args.hole+args.padding
+RADIUS = args.hole/2
+DIMX = 2*(args.dimension+2)*GRID
+DIMY = (args.dimension+2)*GRID
+PI3 = math.pi/3
+
+def draw_grid(cx, cy):
+ for row in range(-int(args.dimension/2), int((args.dimension+1)/2)):
+ cyr = cy+GRID*row*math.sin(PI3)
+ num_col = args.dimension-abs(row)
+ cxr = cx-.5*GRID*(num_col-1.0)
+ for col in range(num_col):
+ print('' % (cxr+col*GRID, cyr, RADIUS))
+
+def draw_plane(cx, cy, interior=False):
+ radius = GRID*args.dimension*0.5+args.outside_padding
+ if not interior:
+ radius += args.thickness
+ turtle = svgturtle.SvgTurtle(cx, cy)
+ turtle.penup()
+ turtle.forward(radius)
+ turtle.right(120)
+ turtle.pendown()
+ if interior:
+ leg = (radius-args.horizontal_finger-args.kerf)/2
+ for side in range(6):
+ turtle.forward(leg)
+ 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(leg)
+ turtle.right(60)
+ else:
+ for side in range(6):
+ turtle.forward(radius)
+ turtle.right(60)
+ print('' % turtle.to_s())
+
+print('')