mirror of
https://github.com/ervanalb/keygen.git
synced 2025-12-16 21:35:28 +00:00
179 lines
14 KiB
OpenSCAD
179 lines
14 KiB
OpenSCAD
$inf=1000;
|
|
$eps=.01;
|
|
|
|
/*
|
|
BROKEN
|
|
function key_make_complex_polygon(paths, reversed) = [
|
|
[for (a=paths, b=a) b],
|
|
[for(i=[0:len(reversed)])
|
|
reversed[i]
|
|
? [for(e=[len(paths[i])-1:-1:0]) e]
|
|
: [for(e=[0:len(paths[i])-1]) e]
|
|
]
|
|
];
|
|
*/
|
|
|
|
function key_move_and_scale(points, scale, offset) = [
|
|
for(p=points) [scale[0] * (p[0] + offset[0]),
|
|
scale[1] * (p[1] + offset[1])]
|
|
];
|
|
|
|
module key_outline(outline_points, thickness, outline_paths=undef) {
|
|
rotate(-90, [0, 1, 0]) rotate(-90, [0, 0, 1]) // Rotate into the correct plane
|
|
linear_extrude(height=thickness, center=true) // Extrude the key outline
|
|
polygon(points=outline_points, paths=outline_paths); // Draw the outline
|
|
}
|
|
|
|
module key_blade(warding, plug_diameter=0) {
|
|
// Draw the blade to infinity in -Y
|
|
// optionally intersected with the plug cylinder
|
|
// to round the bottom
|
|
intersection() {
|
|
rotate(90, [1, 0, 0])
|
|
linear_extrude(height=2*$inf, center=true)
|
|
polygon(warding);
|
|
|
|
// Draw the plug, if a plug diameter is specified
|
|
if(plug_diameter > 0) {
|
|
// Draw infinite cylinder in -Y
|
|
translate([0, 0, 0.5*plug_diameter]) rotate(90, [1, 0, 0])
|
|
cylinder(r=0.5*plug_diameter, h=$inf, $fn=$fn ? 4*$fn : 48);
|
|
}
|
|
}
|
|
}
|
|
|
|
module key_x_line(length) {
|
|
// Hack to draw a line in X
|
|
// since OpenSCAD does not support line primitives
|
|
// Take a 2D square and rotate it
|
|
// When it is orthogonal to the XY plane,
|
|
// it projects down to a line
|
|
rotate(90, [1, 0, 0])
|
|
square([length, length], center=true);
|
|
}
|
|
|
|
module key_warding_cutter(warding, blade_height, cutter_radius, left) {
|
|
neg = left ? -1 : 1;
|
|
translate([neg * -cutter_radius, 0, 0])
|
|
rotate_extrude($fn=$fn ? 4*$fn : 48)
|
|
translate([neg * cutter_radius, 0])
|
|
difference() {
|
|
translate([0, 0.5*blade_height])
|
|
square([2 * cutter_radius, blade_height], center=true);
|
|
minkowski() {
|
|
translate([neg * 1.5 * cutter_radius, 0])
|
|
key_x_line(3 * cutter_radius);
|
|
polygon(warding);
|
|
}
|
|
polygon(warding);
|
|
}
|
|
}
|
|
|
|
module key_emboss(emboss_points, emboss_depth, left, thickness, emboss_paths=undef) {
|
|
translate([(left ? 1 : -1) * 0.5*thickness, 0, 0]) rotate(-90, [0, 1, 0]) rotate(-90, [0, 0, 1]) // Translate and rotate into the correct soot
|
|
linear_extrude(height=2*emboss_depth, center=true) // Extrude the key outline
|
|
polygon(points=emboss_points, paths=emboss_paths); // Draw the outline
|
|
}
|
|
|
|
module key_blank(outline_points,
|
|
warding,
|
|
outline_paths=undef,
|
|
emboss_right_points=[],
|
|
emboss_right_paths=undef,
|
|
emboss_left_points=[],
|
|
emboss_left_paths=undef,
|
|
bow_thickness=0,
|
|
emboss_depth=.1,
|
|
plug_diameter=0,
|
|
scale=[1/96, -1/96],
|
|
offset=[0, 0],
|
|
cutter_radius=10) {
|
|
|
|
// Find the bounding box of the warding
|
|
warding_min = [min([for(e=warding) e[0]]), min([for(e=warding) e[1]])];
|
|
warding_max = [max([for(e=warding) e[0]]), max([for(e=warding) e[1]])];
|
|
|
|
// Apply the given offset to the outline,
|
|
// holes, and emboss
|
|
outline_adj = key_move_and_scale(outline_points, scale, offset);
|
|
emboss_left_adj = key_move_and_scale(emboss_left_points, scale, offset);
|
|
emboss_right_adj = key_move_and_scale(emboss_right_points, scale, offset);
|
|
|
|
// Move the warding profile
|
|
// so that it is centered in X
|
|
// and non-negative in Y
|
|
warding_offset = [-0.5 * (warding_min[0] + warding_max[0]),
|
|
-warding_max[1]];
|
|
warding_adj = key_move_and_scale(warding, scale, warding_offset);
|
|
|
|
// Infer various key properties
|
|
thickness = (bow_thickness == 0) ? abs(scale[0] * (warding_max[0] - warding_min[0])) : bow_thickness;
|
|
blade_height = abs(scale[1] * (warding_max[1] - warding_min[1]));
|
|
|
|
// Cut out the warding milling artifacts
|
|
// from the bow
|
|
difference() {
|
|
// Create the bulk of the keyblank
|
|
// by intersecting the outline
|
|
// with the warding profile
|
|
// and the plug
|
|
intersection() {
|
|
// Draw the key outline and holes
|
|
key_outline(outline_adj, thickness, outline_paths);
|
|
|
|
// Draw the blade, and a giant box where the bow is
|
|
// so that we don't wipe out the bow
|
|
// when the intersection happens
|
|
union() {
|
|
// Fill +Y half-space
|
|
translate([0, $inf/2, 0])
|
|
cube([$inf, $inf, $inf], center=true);
|
|
|
|
key_blade(warding_adj, plug_diameter, $inf);
|
|
}
|
|
}
|
|
// Draw the milling wheels that cut the warding
|
|
if(cutter_radius != 0) {
|
|
key_warding_cutter(warding_adj, blade_height, cutter_radius, false);
|
|
key_warding_cutter(warding_adj, blade_height, cutter_radius, true);
|
|
}
|
|
|
|
// Draw the embossing
|
|
key_emboss(emboss_right_adj, emboss_depth, false, thickness, emboss_right_paths);
|
|
key_emboss(emboss_left_adj, emboss_depth, true, thickness, emboss_left_paths);
|
|
}
|
|
}
|
|
|
|
f1 = [[-91.182522,4.034955],[-92.686430,7.262495],[-94.151272,9.132615],[-95.840725,10.026165],[-98.018462,10.324015],[-100.889552,10.324015],[-100.889552,7.316205],[-98.780182,7.316205],[-97.461819,7.140425],[-96.475492,6.613085],[-95.611234,5.431440],[-94.659082,3.292765],[-94.014552,1.652145],[-102.862212,-19.871295],[-99.053612,-19.871295],[-92.217682,-2.761915],[-85.381742,-19.871295],[-81.573152,-19.871295]];
|
|
|
|
f2 = [[-66.416902,-56.626755],[-66.416902,-53.228315],[-69.580962,-54.400195],[-72.979402,-54.790815],[-75.323150,-54.585737],[-77.002832,-53.970505],[-77.998930,-52.945115],[-78.330962,-51.509565],[-78.091705,-50.391403],[-77.373932,-49.536915],[-75.933502,-48.848435],[-73.526272,-48.189255],[-72.295802,-47.915815],[-69.024319,-46.924605],[-66.866112,-45.591595],[-65.650295,-43.809372],[-65.245022,-41.431445],[-65.396389,-39.987351],[-65.850492,-38.701950],[-66.607329,-37.575241],[-67.666902,-36.607225],[-70.523345,-35.274220],[-74.287992,-34.829885],[-77.959862,-35.181445],[-81.963772,-36.197065],[-81.963772,-39.908005],[-78.037992,-38.345505],[-74.209862,-37.837695],[-71.963770,-38.052537],[-70.303612,-38.697065],[-69.278227,-39.751755],[-68.936432,-41.158005],[-69.185455,-42.451948],[-69.932522,-43.404095],[-71.499905,-44.170698],[-74.248932,-44.908005],[-75.498932,-45.200975],[-78.374907,-46.089645],[-80.323152,-47.349415],[-81.436430,-49.082810],[-81.807522,-51.353315],[-81.670803,-52.808394],[-81.260647,-54.087693],[-80.577053,-55.191209],[-79.620022,-56.118945],[-76.973537,-57.378713],[-73.409082,-57.798635],[-69.659082,-57.505665],[-66.416902,-56.626755]];
|
|
|
|
f3 = [[-166.143462,-64.556445],[-147.705962,-64.556445],[-147.705962,-61.236135],[-162.198152,-61.236135],[-162.198152,-52.603315],[-148.311432,-52.603315],[-148.311432,-49.283005],[-162.198152,-49.283005],[-162.198152,-38.716595],[-147.354402,-38.716595],[-147.354402,-35.396285],[-166.143462,-35.396285]];
|
|
|
|
f4 = [[-184.742272,14.717365],[-184.742272,15.717365],[-50.111412,15.717365],[-173.929772,30.844315],[-173.919772,31.836505],[-77.587742,41.863845],[-150.681492,50.338455],[-150.683492,51.332595],[-85.822162,59.205645],[-85.701072,58.213455],[-146.382712,50.848225],[-72.956932,42.334545],[-72.962932,41.340405],[-169.418012,31.299395],[-41.835972,15.715405],[-41.896572,14.717365]];
|
|
|
|
f5 = [[-124.502832,-57.271285],[-120.909082,-57.271285],[-120.909082,-35.396285],[-124.502832,-35.396285]];
|
|
|
|
f6 = [[-124.502832,-65.786915],[-120.909082,-65.786915],[-120.909082,-61.236135],[-124.502832,-61.236135]];
|
|
|
|
f10 = [[-106.182522,-9.832235],[-106.182522,-8.074415],[-122.705962,-8.074415],[-122.032132,-4.802935],[-121.365630,-3.496783],[-120.479402,-2.410355],[-119.375886,-1.564409],[-118.077057,-0.960163],[-114.893462,-0.476765],[-110.889552,-0.984575],[-107.022362,-2.508015],[-107.022362,0.890425],[-110.987212,2.140425],[-115.108302,2.570115],[-117.589993,2.379685],[-119.800687,1.808395],[-121.740383,0.856245],[-123.409082,-0.476765],[-124.742092,-2.134478],[-125.694242,-4.060748],[-126.265532,-6.255573],[-126.455962,-8.718955],[-126.275298,-11.265340],[-125.733305,-13.533405],[-124.829983,-15.523150],[-123.565332,-17.234575],[-121.984524,-18.618851],[-120.152250,-19.607620],[-118.068509,-20.200881],[-115.733302,-20.398635],[-113.642239,-20.220413],[-111.783110,-19.685745],[-110.155914,-18.794633],[-108.760652,-17.547075],[-107.632720,-16.002886],[-106.827055,-14.202350],[-106.343655,-12.145466],[-106.182522,-9.832235]];
|
|
|
|
h1 = [[-109.776272,-10.886915],[-110.210862,-13.538285],[-111.436432,-15.593955],[-113.301665,-16.912313],[-115.694242,-17.351765],[-118.404202,-16.926960],[-120.518462,-15.652545],[-121.934475,-13.606645],[-122.588772,-10.867385]]; // HOLE
|
|
|
|
f7 = [[-97.666902,-56.431445],[-97.666902,-53.072065],[-100.733302,-54.322065],[-103.819242,-54.751755],[-105.469631,-54.612595],[-106.924710,-54.195115],[-108.184476,-53.499315],[-109.248932,-52.525195],[-110.094878,-51.309375],[-110.699124,-49.868945],[-111.182522,-46.314255],[-110.699124,-42.754683],[-110.094878,-41.308149],[-109.248932,-40.083785],[-108.184476,-39.118209],[-106.924710,-38.428513],[-105.469631,-38.014694],[-103.819242,-37.876755],[-100.733302,-38.286915],[-97.666902,-39.556445],[-97.666902,-36.236135],[-100.791902,-35.181445],[-104.209862,-34.829885],[-106.553614,-35.023976],[-108.643460,-35.606250],[-110.479399,-36.576706],[-112.061432,-37.935345],[-113.334623,-39.623578],[-114.244045,-41.582808],[-114.789698,-43.813033],[-114.971582,-46.314255],[-114.788477,-48.847213],[-114.239162,-51.094528],[-113.323637,-53.056198],[-112.041902,-54.732225],[-110.431794,-56.073779],[-108.550690,-57.032033],[-106.398589,-57.606984],[-103.975492,-57.798635],[-100.733302,-57.447065],[-97.666902,-56.431445]];
|
|
|
|
f8 = [[-128.311432,-53.911915],[-129.639552,-54.419725],[-131.202052,-54.595505],[-133.897367,-54.097458],[-134.981351,-53.474898],[-135.889552,-52.603315],[-137.105377,-50.196093],[-137.510652,-46.919725],[-137.510652,-35.396285],[-141.123932,-35.396285],[-141.123932,-57.271285],[-137.510652,-57.271285],[-137.510652,-53.872845],[-136.206937,-55.606245],[-134.561432,-56.822065],[-132.549710,-57.554493],[-130.147362,-57.798635],[-129.327052,-57.740035],[-128.330962,-57.603315]];
|
|
|
|
f9 = [[-149.034082,-27.156455],[-145.088772,-27.156455],[-145.088772,-14.832235],[-132.002832,-27.156455],[-126.924712,-27.156455],[-141.397362,-13.562705],[-125.889552,2.003705],[-131.084862,2.003705],[-145.088772,-12.039265],[-145.088772,2.003705],[-149.034082,2.003705]];
|
|
|
|
f11 = [[-87.979402,-64.556445],[-87.979402,-53.716595],[-91.299712,-53.716595],[-91.299712,-64.556445]];
|
|
|
|
outline = [[-201.713978,-42.917865],[-158.796072,-85.835715],[-72.960312,-85.835715],[-30.042472,-42.917865],[-12.875352,-42.917865],[-12.875352,-25.750755],[175.963268,-25.750755],[201.713978,-0.000045],[175.963268,25.750665],[-12.875352,25.750665],[-12.875352,42.917865],[-30.042472,42.917865],[-72.960312,85.835715],[-158.796072,85.835715],[-201.713978,42.917865]];
|
|
|
|
warding = [[235.507438,37.543405],[235.507438,35.772795],[235.507438,34.002175],[235.507438,32.231565],[235.507438,30.460965],[235.507438,28.690345],[235.507438,26.919735],[235.507438,25.149115],[235.507438,23.378505],[234.492508,21.694495],[233.477568,20.010495],[232.462638,18.326465],[231.447718,16.642455],[230.432798,14.958445],[229.417868,13.274435],[228.402938,11.590405],[227.388008,9.906405],[226.974108,9.043625],[226.796408,8.260805],[226.819908,7.560055],[227.009558,6.943415],[227.330378,6.412945],[227.747308,5.970695],[228.225348,5.618715],[228.729498,5.359085],[229.576738,5.002485],[230.423978,4.645875],[231.271238,4.289275],[232.118478,3.932665],[232.965738,3.576065],[233.812988,3.219455],[234.660228,2.862845],[235.507468,2.506245],[235.507468,-2.173475],[235.507468,-6.853175],[235.507468,-11.532895],[235.507468,-16.212605],[235.507468,-20.892315],[235.507468,-25.572025],[235.507468,-30.251745],[235.507468,-34.931455],[234.408708,-34.931455],[233.309948,-34.931455],[232.211158,-34.931455],[231.112398,-34.931455],[230.013628,-34.931455],[228.914858,-34.931455],[227.816078,-34.931455],[226.717308,-34.931455],[226.717308,-31.123275],[226.717308,-27.315065],[226.717308,-23.506885],[226.717308,-19.698675],[226.717308,-15.890495],[226.717308,-12.082285],[226.717308,-8.274105],[226.717308,-4.465895],[225.835398,-4.229595],[224.953508,-3.993285],[224.071618,-3.756975],[223.189718,-3.520685],[222.307808,-3.284365],[221.425918,-3.048065],[220.544008,-2.811755],[219.662118,-2.575455],[219.662118,-0.707875],[219.662118,1.159705],[219.662118,3.027295],[219.662118,4.894875],[219.662118,6.762455],[219.662118,8.630035],[219.662118,10.497615],[219.662118,12.365195],[220.394628,13.661675],[221.127148,14.958175],[221.859668,16.254665],[222.592158,17.551155],[223.324678,18.847645],[224.057198,20.144135],[224.789718,21.440625],[225.522228,22.737115],[225.967728,23.715035],[226.184078,24.630705],[226.194378,25.471975],[226.022028,26.226595],[225.690088,26.882395],[225.221788,27.427175],[224.640318,27.848735],[223.968848,28.134875],[223.430498,28.297725],[222.892148,28.460575],[222.353778,28.623425],[221.815428,28.786265],[221.277088,28.949095],[220.738718,29.111945],[220.200368,29.274785],[219.662018,29.437635],[219.662018,30.450855],[219.662018,31.464075],[219.662018,32.477295],[219.662018,33.490515],[219.662018,34.503735],[219.662018,35.516965],[219.662018,36.530175],[219.662018,37.543405],[221.642688,37.543405],[223.623348,37.543405],[225.604028,37.543405],[227.584698,37.543405],[229.565368,37.543405],[231.546048,37.543405],[233.526698,37.543405]];
|
|
|
|
|
|
holes = [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11];
|
|
|
|
key_blank(outline, warding, emboss_right_points=f1, offset=-outline[9], plug_diameter=20, scale=[.1, -.1]);
|