From 1018af7e933090c8a529a9b860be18848168d243 Mon Sep 17 00:00:00 2001 From: Eric Van Albert Date: Fri, 9 Jun 2017 22:09:55 -0400 Subject: [PATCH] add key bitting cutting code, add picture, and update README --- README.md | 15 ++++++++++++++- doc/key.png | Bin 0 -> 19395 bytes keygen.scad | 29 +++++++++++++++++++++++++++++ sc4.scad | 27 +++++++++++++++++++-------- 4 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 doc/key.png diff --git a/README.md b/README.md index 8378399..7681626 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # keygen -OpenSCAD tools for generating physical keys +Tools for generating physical keys. + +![152698](doc/key.png "Key in OpenSCAD") + +## How it Works +1. Get some nice pictures of the side and tip of your key. +I recommend a flatbed scanner. +2. Trace the key outline, warding, and embossing in Inkscape +3. Use the provided Inkscape plugin to convert the paths to OpenSCAD polygons. +4. Look up online the various parameters of your key, such as plug diameter, +cut depths and locations. +5. Use the provided OpenSCAD functions `key_code_to_heights`, +`key_blank` and `key_bitting` to generate a 3D model of your key. +6. Send the key to be 3D printed. diff --git a/doc/key.png b/doc/key.png new file mode 100644 index 0000000000000000000000000000000000000000..ab7716d0ba30889ab86b2aef63d698c29e10c4d9 GIT binary patch literal 19395 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
q6uar0ZF^?evE5 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 Ciu3{i literal 0 HcmV?d00001 diff --git a/keygen.scad b/keygen.scad index b88c827..5b11fe5 100644 --- a/keygen.scad +++ b/keygen.scad @@ -129,4 +129,33 @@ module key_blank(outline_points, key_emboss(emboss_right_adj, emboss_depth, false, thickness, emboss_right_paths); key_emboss(emboss_left_adj, emboss_depth, true, thickness, emboss_left_paths); } +} + +function key_code_to_heights(code, depth_table) = [for(i=[0:len(code)-1]) depth_table[search(code[i], "0123456789")[0]]]; + +module key_bitting_cutter(flat, angle, tool_height) { + polygon([[-0.5 * flat, 0], + [0.5 * flat, 0], + [0.5 * flat + tan(0.5 * angle) * tool_height, tool_height], + [0.5 * flat - tan(0.5 * angle) * tool_height, tool_height]]); +} + +module key_bitting(heights, + locations, + flat, + angle=100, + cutter_width=5, + cutter_height=5) { + // Rotate the cutting tool to the proper orientation + rotate(-90, [0, 0, 1]) rotate(90, [1, 0, 0]) + // Union together a handful of trapezoids + // that comprise the cuts + union() { + for(i=[0:len(heights)-1]) { + // Move to the proper location and height + translate([locations[i], heights[i]]) + linear_extrude(height=cutter_width, center=true) + key_bitting_cutter(flat, angle, cutter_height); + } + } } \ No newline at end of file diff --git a/sc4.scad b/sc4.scad index 8f6140c..2b190e5 100644 --- a/sc4.scad +++ b/sc4.scad @@ -1,11 +1,22 @@ use include -key_blank(outline_points, - warding_points, - outline_paths=outline_paths, - emboss_right_points=emboss_points, - emboss_right_paths=emboss_paths, - emboss_left_points=emboss_points, - emboss_left_paths=emboss_paths, - offset=-outline_points[187]); +bitting_code = "024689"; + +cut_locations = [for(i=[.231, .3872, .5434, .6996, .8558, 1.012]) i*25.4]; +depth_table = [for(i=[0.335:-0.015:0.199]) i*25.4]; + +heights = key_code_to_heights(bitting_code, depth_table); + +difference() { + key_blank(outline_points, + warding_points, + outline_paths=outline_paths, + emboss_right_points=emboss_points, + emboss_right_paths=emboss_paths, + emboss_left_points=emboss_points, + emboss_left_paths=emboss_paths, + offset=-outline_points[187], + plug_diameter=12.7); + key_bitting(heights, cut_locations, .7874); +} \ No newline at end of file