removed trashes

This commit is contained in:
pseudoku 2019-08-06 01:29:49 -05:00
parent bd2f89109a
commit 6ff933aed5
10 changed files with 59 additions and 330447 deletions

View file

@ -9,7 +9,7 @@ use <skin.scad>
//DES (Distorted Elliptical Saddle) Choc Chord version Chicago Stenographer
/*Tester */
keycap(keyID = 5, cutLen = 0, Stem =true, Dish = true, Stab = 0 , visualizeDish = false, crossSection = false, homeDot = false, Legends = false);
keycap(keyID = 7, cutLen = 0, Stem =true, Dish = true, Stab = 0 , visualizeDish = false, crossSection = false, homeDot = false, Legends = false);
// translate([0,19, 0])keycap(keyID = 3, cutLen = 0, Stem =true, Dish = true, visualizeDish = true, crossSection = true, homeDot = false, Legends = false);
// translate([0,38, 0])mirror([0,1,0])keycap(keyID = 2, cutLen = 0, Stem =true, Dish = true, visualizeDish = false, crossSection = true, homeDot = false, Legends = false);
@ -45,8 +45,8 @@ layers = 40; //resolution of vertical Sweep: 50 for output
//---Stem param
slop = 0.3;
stemRot = 0;
stemWid = 6;
stemLen = 8;
stemWid = 8;
stemLen = 6;
stemCrossHeight = 1.8;
extra_vertical = 0.6;
stemLayers = 50; //resolution of stem to cap top transition
@ -63,8 +63,8 @@ keyParameters = //keyParameters[KeyID][ParameterID]
[17.06, 35.16, 7, 3, 6.2, 0, 0, -3, -7, -0, 2, 2, 4, 4, 1, 4, 1, 2], //Chicago T0 R1 2u
[17.06, 17.06, 7, 4, 7.4, 0, .0, -6, 4, 0, 2, 2, 4, 4, 1, 4, 1, 2], //Chicago T0 R2 1u
[17.06, 35.16, 7, 3, 6.2, 0, 0, -3, 7, -0, 2, 2, 4, 4, 1, 4, 1, 2], //Chicago T1 R2 2u
[17.06*1.50,17.16, 7, 5, 5.5, 0, 0, -2, 4, 5, 2, 2, 4, 4, 1, 4, 1, 2], //Chicago T2 R1 1.25
[17.16*1.25,17.16, 7, 5, 6.5, 0, 0, -2, 3, -0, 2, 2, 4, 4, 1, 4, 1, 2] //Chicago T3 R1 1.25
[17.06*1.50,17.16, 7, 5, 6.2, 0, 0, -2, 4, 5, 2, 2, 4, 4, 1, 4, 1, 2], //Chicago T2 R1 1.25
[17.16*1.25,17.16, 7, 5, 6.8, 0, 0, -2, 3, -0, 2, 2, 4, 4, 1, 4, 1, 2] //Chicago T3 R1 1.25
];

View file

@ -13,17 +13,17 @@ Version 2: Eliptical Rectangle
//Stab = 24 for
//TODO add shift
keycap(keyID = 1, cutLen = 0, Stem =false, Dish = true, Stab = 0 , visualizeDish = true, crossSection = false, homeDot = false, Legends = false);
keycap(keyID = 3, cutLen = 0, Stem =true, Dish = true, Stab = 0 , visualizeDish = false, crossSection = false, homeDot = false, Legends = false);
// translate([0,19, 0])keycap(keyID = 3, cutLen = 0, Stem =true, Dish = true, visualizeDish = true, crossSection = true, homeDot = false, Legends = false);
// translate([0,38, 0])mirror([0,1,0])keycap(keyID = 2, cutLen = 0, Stem =true, Dish = true, visualizeDish = false, crossSection = true, homeDot = false, Legends = false);
RowHome = [0,2.5,5,2.5,0,0];
//for(Col = [0:0]){
// for(Row = [1:2]){
// translate([19*Col, 19*Row +RowHome[Col], 0])keycap(keyID = Col*4+Row, cutLen = 0, Stem = true, Dish = true, visualizeDish = true, crossSection = true,Legends = false);
//for(Col = [0:5]){
// for(Row = [1:3]){
// translate([19*Col, 19*Row +RowHome[Col], 0])keycap(keyID = Col*4+Row, cutLen = 0, Stem = true, Dish = true, visualizeDish = false, crossSection = false,Legends = false);
// }
//}
//
//// thumb
// translate([-15, -4, 0])rotate([0,0,30])keycap(keyID = 0, cutLen = 0, Stem =false, Dish = true, visualizeDish = false, crossSection = false);
// translate([10, 0, 0])rotate([0,0,15])keycap(keyID = 4, cutLen = 0, Stem =false, Dish = true, visualizeDish = false, crossSection = false);
@ -32,10 +32,10 @@ RowHome = [0,2.5,5,2.5,0,0];
//Parameters
wallthickness = 1.75;
topthickness = 3; //2 for phat 3 for chicago
stepsize = 50; //resolution of Trajectory
step = 2; //resolution of ellipes
stepsize = 40; //resolution of Trajectory
step = 4; //resolution of ellipes
fn = 32; //resolution of Rounded Rectangles: 60 for output
layers = 50; //resolution of vertical Sweep: 50 for output
layers = 40; //resolution of vertical Sweep: 50 for output
//---Stem param
slop = 0.3;
@ -45,75 +45,75 @@ stemLen = 5.5;
stemCrossHeight = 4;
extra_vertical = 0.6;
stemLayers = 50; //resolution of stem to cap top transition
#square([18.16, 18.16], center = true);
//#square([18.16, 18.16], center = true);
keyParameters = //keyParameters[KeyID][ParameterID]
[
// BotWid, BotLen, TWDif, TLDif, keyh, WSft, LSft XSkew, YSkew, ZSkew, WEx, LEx, CapR0i, CapR0f, CapR1i, CapR1f, CapREx, StemEx
//Column 0
[17.16, 17.16*1.5, 6, 6, 12, 0, 0, -13, -10, -5, 2, 2, .2, 3, 2, 6, 2, 2], //R5 0
[17.16, 17.16, 6, 6, 8+4, 0, 0, 10, -10, -5, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 7, 7, 7+4, 0, 0, -2, -10, -5, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8+4, 0, 0, -10, -10, -5, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16*1.5, 6, 6, 14, 0, 0, -13, -10, -5, 2, 2, 2, 6, 2, 4, 2, 2], //R5 0
[17.16, 17.16, 6.5, 6.5, 8+4, 0, 0, 10, -10, -5, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5, 7+4, 0, 0, -2, -10, -5, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8+4, 0, 0, -10, -10, -5, 2, 2, 2, 6, 2, 4, 2, 2], //R2
//Column 1
[17.16, 17.16, 6, 6, 10, 0, 0, -13, 5, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R5 4
[17.16, 17.16, 7, 7, 8+3, 0, 0, 5, -3, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R4
[17.16, 17.16, 7, 7,7+2.5, 0, 0, -2, -3, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8+3, 0, 0, -12, -3, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16, 6, 6, 13, 0, 0, -13, 5, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R5 4
[17.16, 17.16, 6.5, 6.5, 8+3, 0, 0, 5, -3, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5,7+2.5, 0, 0, -2, -3, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8+3, 0, 0, -12, -3, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R2
//Column 2 middle
[17.16, 17.16, 6, 6, 12, 0, 0, -13, 10, 15, 2, 2, .2, 3, 2, 6, 2, 2], //R5 8
[17.16, 17.16, 7, 7, 8, 0, 0, 5, 0, 0, 2, 2, 1, 5, 1, 3, 2, 2], //R4
[17.16, 17.16, 7, 7, 7, 0, 0, -2, 0, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8, 0, 0, -12, 0, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16, 6, 6, 13, 0, 0, -13, 10, 15, 2, 2, 2, 6, 2, 4, 2, 2], //R5 8
[17.16, 17.16, 6.5, 6.5, 8, 0, 0, 5, 0, 0, 2, 2, 1, 5, 1, 3, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5, 7, 0, 0, -2, 0, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8, 0, 0, -12, 0, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R2
//Column 3
[17.16, 17.16, 6, 6, 11+3, 0, 0, 13, -4, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R5 12
[17.16, 17.16, 7, 7, 8+3, 0, 0, 5, -4, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R4
[17.16, 17.16, 7, 7, 7+3, 0, 0, -2, -4, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8+3, 0, 0, -10, -4, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16, 6, 6, 11+3, 0, 0, 13, -4, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R5 12
[17.16, 17.16, 6.5, 6.5, 8+3, 0, 0, 5, -4, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5, 7+3, 0, 0, -2, -4, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8+3, 0, 0, -10, -4, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R2
//Column 4
[17.16, 17.16, 6, 6,11+5.5, 0, 0, 13, -10, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R5 16
[17.16, 17.16, 7, 7,8+5.5, 0, 0, 5, -10, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R4
[17.16, 17.16, 7, 7,7+5.5, 0, 0, -5, -10, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8+4, 0, 0, -12, 5, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16, 6, 6,11+5.5, 0, 0, 13, -10, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R5 16
[17.16, 17.16, 6.5, 6.5,8+5.5, 0, 0, 5, -10, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5,7+5.5, 0, 0, -5, -10, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8+4, 0, 0, -12, 5, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R2
//Column 5
[17.16, 17.16, 6, 6, 11+4, 0, 0, 13, -6, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R5 20
[17.16, 17.16, 7, 7, 8+4, 0, 0, 5, -6, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R4
[17.16, 17.16, 7, 7, 7+4, 0, 0, -2, -6, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R3 Home
[17.16, 17.16, 7, 7, 8+6, 0, 0, -12, 10, 0, 2, 2, .2, 3, 2, 6, 2, 2], //R2
[17.16, 17.16, 6, 6, 11+4, 0, 0, 13, -6, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R5 20
[17.16, 17.16, 6.5, 6.5, 8+4, 0, 0, 5, -6, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R4
[17.16, 17.16, 6.5, 6.5, 7+4, 0, 0, -2, -6, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R3 Home
[17.16, 17.16, 6.5, 6.5, 8+6, 0, 0, -12, 10, 0, 2, 2, 2, 6, 2, 4, 2, 2], //R2
];
dishParameters = //dishParameter[keyID][ParameterID]
[
//FFwd1 FFwd2 FPit1 FPit2 DshDep DshHDif FArcIn FArcFn FArcEx BFwd1 BFwd2 BPit1 BPit2 BArcIn BArcFn BArcEx
//Column 0
[ 9, 3, 10, -42, 4, 1.7, 8.5, 12, 2, 10, 4, 8, -30, 8.5, 18, 2], //R5
[ 6, 3, 15, -50, 5, 1.7, 9, 19, 2, 5, 4, 13, -50, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 8.8, 15, 2, 6, 4, 13, -30, 8.8, 16, 2], //R2
[ 9, 4, 10, -42, 4, 1.7, 9.5, 12, 2, 10, 4, 8, -30, 9.5, 20, 2], //R5
[ 6, 3, 15, -50, 5, 1.7, 9.5, 19, 2, 5, 4, 13, -50, 9.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 9.5, 15, 2, 5, 4, 13, -30, 9.5, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 9.8, 15, 2, 6, 4, 13, -30, 9.8, 16, 2], //R2
//Column 1
[ 5, 3.5, 5, -48, 4, 1.7, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 15, -50, 5, 1.7, 8, 15, 2, 6, 4, 10, -30, 8, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.7, 8.2, 15, 2, 5, 4, 13, -30, 8.2, 16, 2], //R3
[ 6, 3, 12, -50, 5, 1.7, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 5, 4.3, 5, -48, 4, 1.7, 8.8, 10, 2, 6, 4, 13, -30, 8.8, 16, 2], //R5
[ 6, 3, 15, -50, 5, 1.7, 9, 15, 2, 6, 4, 10, -30, 9, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.7, 9, 15, 2, 5, 4, 13, -30, 9, 16, 2], //R3
[ 6, 3, 12, -50, 5, 1.7, 9, 15, 2, 6, 4, 13, -30, 9, 16, 2], //R2
//Column 2
[ 5, 3.5, 5, -48, 4, 1.7, 9.3, 10, 2, 6, 4, 13, -30, 9.3, 18, 2], //R5
[ 6, 3, 18, -50, 5, 1.7, 8, 15, 2, 6, 4, 13, -30, 8, 15, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8, 15, 2, 5, 4, 13, -30, 8, 15, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 8, 15, 2, 6, 4, 13, 30, 8, 16, 2], //R2
[ 5, 4.3, 5, -48, 4, 1.7, 9.3, 10, 2, 6, 3, 13, -30, 9.3, 22, 2], //R5
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 15, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 15, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 8.8, 15, 2, 6, 4, 13, 30, 8.8, 16, 2], //R2
//Column 3
[ 5, 3, 5, -50, 5, 1.5, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 5, 1.6, 8.5, 15, 2, 6, 4, 10, -30, 8.5, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.6, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 15, -50, 5, 1.6, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 5, 1.6, 9.5, 18, 2, 6, 4, 10, -30, 9.5, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.6, 9.5, 15, 2, 5, 4, 13, -30, 9.5, 16, 2], //R3
[ 6, 3, 15, -50, 5, 1.6, 9.5, 15, 2, 6, 4, 13, -30, 9.5, 16, 2], //R2
//Column 4
[ 5, 3, 5, -50, 5, 1.7, 8.5, 12, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 5, 1.7, 8.5, 17, 2, 6, 4, 10, -30, 8.5, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 8.6, 15, 2, 6, 4, 13, -30, 8.6, 16, 2], //R2
[ 6, 3, 18, -50, 5, 1.7, 9.5, 17, 2, 6, 4, 10, -30, 9.5, 16, 2], //R4
[ 6, 3, 15, -50, 5, 1.7, 9.5, 15, 2, 5, 4, 13, -30, 9.5, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 9.6, 15, 2, 6, 4, 13, -30, 9.6, 16, 2], //R2
//Column 5
[ 5, 3, 5, -50, 5, 1.7, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 8.8, 15, 2, 6, 4, 13, -30, 8.8, 16, 2], //R2
[ 6, 3, 18, -50, 5, 1.7, 9.2, 15, 2, 6, 4, 13, -30, 9.2, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 9.2, 15, 2, 5, 4, 13, -30, 9.2, 16, 2], //R3
[ 6, 3, 18, -50, 5, 1.7, 9.6, 15, 2, 6, 4, 13, -30, 9.6, 16, 2], //R2
];
function FrontForward1(keyID) = dishParameters[keyID][0]; //

View file

@ -1,198 +0,0 @@
use <scad-utils/morphology.scad> //for cheaper minwoski
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <sweep.scad>
use <skin.scad>
//TODO: Make Alias for key[n]
wallthickness = 2.0;
topthickness = 2.0;
key =
//[
// BotWid, BotLen, TopWDif, TopLDif, height, WShift, LShift XAngSkew, YAngSkew, ZAngSkew LExpo, WExpo, CapRadIn, CapRadFn, CapRadExpd
[18.16*1.5, 18.16, 4, 4, 3.8, 0, 0, -3, -0, 0, 2, 5, .2, 3, 2];
//];
step = 2;
function ellipse(a, b, d = 0, rot1 = 0, rot2 = 360) = [for (t = [rot1:step:rot2]) [a*cos(t)+a, b*sin(t)*(1+d*cos(t))]]; //Centered at a apex to avoid inverted face
function DishShape (a,b,c,d) =
concat(
// [[c+a,b]],
ellipse(a, b, d = 0,rot1 = 90, rot2 = 270)
// [[c+a,-b]]
);
function oval_path(theta, phi, a, b, c, deform = 0) = [
a*cos(theta)*cos(phi), //x
c*sin(theta)*(1+deform*cos(theta)) , //
b*sin(phi),
];
path_trans2 = [for (t=[0:step:180]) translation(oval_path(t,0,10,15,2,0))*rotation([0,90,0])];
//------------Define the trajectory of the dish shsape cuts
FrontTraj = [
trajectory(forward = 6, pitch = 12),
trajectory(forward = 3, pitch = -50)
];
BackTraj = [
trajectory(forward = 6, pitch = 10),
trajectory(forward = 4, pitch = -30),
// trajectory(forward = 10, pitch = -20, roll = 0)
];
//quantized trajectory to be fed into transform
stepsize = 50;
fn=60;
FrontPath = quantize_trajectories(FrontTraj, steps = stepsize, loop=false, start_position= $t*4);
BackPath = quantize_trajectories(BackTraj, steps = stepsize, loop=false, start_position= $t*4);
FrontCurve = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(2.5, 11, 1, d = 0)) ];
BackCurve = [ for(i=[0:len(BackPath)-1]) transform(BackPath[i], DishShape(2.5, 11, 1, d = 0)) ];
FrontCurve2 = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(2+2, 10+2, 2, d = 0)) ];
//--------------For Cap
layers = 50;
function CapTranslation(t) =
[
((1-t)/layers*key[5]), //X shift
((1-t)/layers*key[6]), //Y shift
(t/layers*key[4]) //Z shift
];
function InnerTranslation(t) =
[
((1-t)/layers*key[5]), //X shift
((1-t)/layers*key[6]), //Y shift
(t/layers*(key[4]-topthickness)) //Z shift
];
function CapRotation(t) =
[
((1-t)/layers*key[7]), //X shift
((1-t)/layers*key[8]), //Y shift
((1-t)/layers*key[9]) //Z shift
];
function CapTransform(t) =
[
pow(t/layers, key[10])*(key[0]-key[2]) + (1-pow(t/layers, key[10]))*key[0],
pow(t/layers, key[11])*(key[1]-key[3]) + (1-pow(t/layers, key[11]))*key[1]
];
function InnerTransform(t) =
[
pow(t/layers, key[10])*(key[0]-key[2]-wallthickness) + (1-pow(t/layers, key[10]))*(key[0]-wallthickness),
pow(t/layers, key[11])*(key[1]-key[3]-wallthickness) + (1-pow(t/layers, key[11]))*(key[1]-wallthickness)
];
function CapRadius(t) = pow(t/layers, key[14])*key[13] + (1-pow(t/layers, key[14]))*key[12];
///KEY Build
mirror([0,1,0])difference(){
union(){
difference(){
skin([for (i=[0:layers-1])transform(translation(CapTranslation(i)) * rotation(CapRotation(i)), rounded_rectangle_profile(CapTransform(i),fn=fn,r=CapRadius(i)))]);
//use intersection with stem here?
translate([0,0,-.001])skin([for (i=[0:layers-1])transform(translation(InnerTranslation(i)) * rotation(CapRotation(i)), rounded_rectangle_profile(InnerTransform(i),fn=fn,r=CapRadius(i)))]);
}
rotate([0,0,stemRot])choc_stem();
//cut for fonts and extra pattern for light?
}
// #rotate([-key[7],key[8],key[9]])translate([0,4,key[4]-2.5])linear_extrude(height = 0.5)text( text = "Why?", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
// #rotate([-key[7],key[8],key[9]])translate([0,-3.5,0])linear_extrude(height = 0.5)text( text = "Me", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
#translate([0,.00001,key[4]-1.5])rotate([0,-key[8],0])rotate([0,-90+key[7],90-key[9]])skin(FrontCurve);
#translate([0,0,key[4]-1.5])rotate([0,-key[8],0])rotate([0,-90-key[7],270-key[9]])skin(BackCurve);
// translate([0,-10-3,-.1])cube([20,20,15],center = true);
}
//------------------stems
$fn = 32;
slop = 0.3;
stemRot = 0;
extra_vertical = 0.6;
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
function outer_cherry_stabilizer_stem(slop) = [4.85 - slop * 2, 6.05 - slop * 2];
function outer_box_cherry_stem(slop) = [6 - slop, 6 - slop];
// .005 purely for aesthetics, to get rid of that ugly crosshatch
function cherry_cross(slop, extra_vertical = 0) = [
// horizontal tine
[4.03 + slop, 1.15 + slop / 3],
// vertical tine
[1.25 + slop / 3, 4.23 + extra_vertical + slop / 3 + .005],
];
module inside_cherry_cross(slop) {
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = 4) {
square(cherry_cross(slop, extra_vertical)[0], center=true);
square(cherry_cross(slop, extra_vertical)[1], center=true);
}
}
// Guides to assist insertion and mitigate first layer squishing
{
for (i = cherry_cross(slop, extra_vertical)) hull() {
linear_extrude(height = 0.01, center = false) offset(delta = 0.4) square(i, center=true);
translate([0, 0, 0.5]) linear_extrude(height = 0.01, center = false) square(i, center=true);
}
}
}
module cherry_stem(depth, slop) {
difference(){
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square(outer_cherry_stem(slop) - [2,2], center=true);
}
}
inside_cherry_cross(slop);
}
}
module choc_stem() {
translate([5.7/2,0,-3.4/2+2])difference(){
cube([1.25,3, 3.4], center= true);
translate([3.9,0,0])cylinder(d=7,3.4,center = true);
translate([-3.9,0,0])cylinder(d=7,3.4,center = true);
}
translate([-5.7/2,0,-3.4/2+2])difference(){
cube([1.25,3, 3.4], center= true);
translate([3.9,0,0])cylinder(d=7,3.4,center = true);
translate([-3.9,0,0])cylinder(d=7,3.4,center = true);
}
}
/// ----- helper functions
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, fn) * [size[0]/2-r,0]
+ sign_y(index, fn) * [0,size[1]/2-r]
];
function sign_x(i,n) =
i < n/4 || i > n-n/4 ? 1 :
i > n/4 && i < n-n/4 ? -1 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,304 +0,0 @@
use <scad-utils/morphology.scad> //for cheaper minwoski
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <sweep.scad>
use <skin.scad>
use <Switch.scad>
//DES (Distorted Elliptical Saddle) Profile for 6x3 and corne thumb
//TODO add shift
keycap(keyID = 0, cutLen = 0, Stem =true, Dish = false, visualizeDish = true, crossSection = false, homeDot = false, Legends = false);
//Parameters
wallthickness = 1.75;
topthickness = 2.25;
stepsize = 50; //resolution of Trajectory
step = 2; //resolution of ellipes
fn = 64; //resolution of Rounded Rectangles: 60 for output
layers = 50; //resolution of vertical Sweep: 50 for output
//---Stem param
slop = 0.3;
stemRot = 0;
stemWid = 7.2;
stemLen = 5.5;
stemCrossHeight = 4;
extra_vertical = 0.6;
stemLayers = 50; //resolution of stem to cap top transition
//---SwitchCeption Param
ChocAng = [55,5,0];
ChocLoc = [0,-6.0 ,7.5];
keyParameters = //keyParameters[KeyID][ParameterID]
[
// BotWid, BotLen, TWDif, TLDif, keyh, WSft, LSft XSkew, YSkew, ZSkew, WEx, LEx, CapRIn, CapRFn, CapREx, StemEx
//Column 0
[18.16*1.25, 18.16+1, 6, 6, 13, 0, -2, -10, -5, 0, 2, 2, .2, 2, 1, 2], //R5 0
];
function BottomWidth(keyID) = keyParameters[keyID][0]; //
function BottomLength(keyID) = keyParameters[keyID][1]; //
function TopWidthDiff(keyID) = keyParameters[keyID][2]; //
function TopLenDiff(keyID) = keyParameters[keyID][3]; //
function KeyHeight(keyID) = keyParameters[keyID][4]; //
function TopWidShift(keyID) = keyParameters[keyID][5];
function TopLenShift(keyID) = keyParameters[keyID][6];
function XAngleSkew(keyID) = keyParameters[keyID][7];
function YAngleSkew(keyID) = keyParameters[keyID][8];
function ZAngleSkew(keyID) = keyParameters[keyID][9];
function WidExponent(keyID) = keyParameters[keyID][10];
function LenExponent(keyID) = keyParameters[keyID][11];
function ChamfInitRad(keyID) = keyParameters[keyID][12];
function ChamfFinRad(keyID) = keyParameters[keyID][13];
function ChamExponent(keyID) = keyParameters[keyID][14];
function StemExponent(keyID) = keyParameters[keyID][15];
dishParameters = //dishParameter[keyID][ParameterID]
[
//FFwd1 FFwd2 FPit1 FPit2 DshDep DshHDif FArcIn FArcFn FArcEx BFwd1 BFwd2 BPit1 BPit2 BArcIn BArcFn BArcEx
//Column 0
[ 9, 3, 10, -42, 4, 1.7, 8.5, 12, 2, 10, 4, 8, -30, 8.5, 18, 2], //R5
];
function FrontForward1(keyID) = dishParameters[keyID][0]; //
function FrontForward2(keyID) = dishParameters[keyID][1]; //
function FrontPitch1(keyID) = dishParameters[keyID][2]; //
function FrontPitch2(keyID) = dishParameters[keyID][3]; //
function DishDepth(keyID) = dishParameters[keyID][4]; //
function DishHeightDif(keyID) = dishParameters[keyID][5]; //
function FrontInitArc(keyID) = dishParameters[keyID][6];
function FrontFinArc(keyID) = dishParameters[keyID][7];
function FrontArcExpo(keyID) = dishParameters[keyID][8];
function BackForward1(keyID) = dishParameters[keyID][9]; //
function BackForward2(keyID) = dishParameters[keyID][10]; //
function BackPitch1(keyID) = dishParameters[keyID][11]; //
function BackPitch2(keyID) = dishParameters[keyID][12]; //
function BackInitArc(keyID) = dishParameters[keyID][13];
function BackFinArc(keyID) = dishParameters[keyID][14];
function BackArcExpo(keyID) = dishParameters[keyID][15];
function FrontTrajectory(keyID) =
[
trajectory(forward = FrontForward1(keyID), pitch = FrontPitch1(keyID)), //more param available: yaw, roll, scale
trajectory(forward = FrontForward2(keyID), pitch = FrontPitch2(keyID)) //You can add more traj if you wish
];
function BackTrajectory (keyID) =
[
trajectory(forward = BackForward1(keyID), pitch = BackPitch1(keyID)),
trajectory(forward = BackForward2(keyID), pitch = BackPitch2(keyID)),
];
//------- function defining Dish Shapes
function ellipse(a, b, d = 0, rot1 = 0, rot2 = 360) = [for (t = [rot1:step:rot2]) [a*cos(t)+a, b*sin(t)*(1+d*cos(t))]]; //Centered at a apex to avoid inverted face
function DishShape (a,b,c,d) =
concat(
// [[c+a,b]],
ellipse(a, b, d = 0,rot1 = 90, rot2 = 270)
// [[c+a,-b]]
);
function oval_path(theta, phi, a, b, c, deform = 0) = [
a*cos(theta)*cos(phi), //x
c*sin(theta)*(1+deform*cos(theta)) , //
b*sin(phi),
];
path_trans2 = [for (t=[0:step:180]) translation(oval_path(t,0,10,15,2,0))*rotation([0,90,0])];
//--------------Function definng Cap
function CapTranslation(t, keyID) =
[
((1-t)/layers*TopWidShift(keyID)), //X shift
((1-t)/layers*TopLenShift(keyID)), //Y shift
(t/layers*KeyHeight(keyID)) //Z shift
];
function InnerTranslation(t, keyID) =
[
((1-t)/layers*TopWidShift(keyID)), //X shift
((1-t)/layers*TopLenShift(keyID)), //Y shift
(t/layers*(KeyHeight(keyID)-topthickness)) //Z shift
];
function CapRotation(t, keyID) =
[
((1-t)/layers*XAngleSkew(keyID)), //X shift
((1-t)/layers*YAngleSkew(keyID)), //Y shift
((1-t)/layers*ZAngleSkew(keyID)) //Z shift
];
function CapTransform(t, keyID) =
[
pow(t/layers, WidExponent(keyID))*(BottomWidth(keyID) -TopLenDiff(keyID)) + (1-pow(t/layers, WidExponent(keyID)))*BottomWidth(keyID) ,
pow(t/layers, LenExponent(keyID))*(BottomLength(keyID)-TopLenDiff(keyID)) + (1-pow(t/layers, LenExponent(keyID)))*BottomLength(keyID)
];
function CapRadius(t, keyID) = pow(t/layers, ChamExponent(keyID))*ChamfFinRad(keyID) + (1-pow(t/layers, ChamExponent(keyID)))*ChamfInitRad(keyID);
function InnerTransform(t, keyID) =
[
pow(t/layers, WidExponent(keyID))*(BottomWidth(keyID) -TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/layers, WidExponent(keyID)))*(BottomWidth(keyID) -wallthickness*2),
pow(t/layers, LenExponent(keyID))*(BottomLength(keyID)-TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/layers, LenExponent(keyID)))*(BottomLength(keyID)-wallthickness*2)
];
function StemTranslation(t, keyID) =
[
((1-t)/stemLayers*TopWidShift(keyID)), //X shift
((1-t)/stemLayers*TopLenShift(keyID)), //Y shift
stemCrossHeight+.1 + (t/stemLayers*(KeyHeight(keyID)- topthickness - stemCrossHeight-.1)) //Z shift
];
function StemRotation(t, keyID) =
[
((1-t)/stemLayers*XAngleSkew(keyID)), //X shift
((1-t)/stemLayers*YAngleSkew(keyID)), //Y shift
((1-t)/stemLayers*ZAngleSkew(keyID)) //Z shift
];
function StemTransform(t, keyID) =
[
pow(t/stemLayers, StemExponent(keyID))*(BottomWidth(keyID) -TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/stemLayers, StemExponent(keyID)))*(stemWid - 2*slop),
pow(t/stemLayers, StemExponent(keyID))*(BottomLength(keyID)-TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/stemLayers, StemExponent(keyID)))*(stemLen - 2*slop)
];
function StemRadius(t, keyID) = pow(t/stemLayers,3)*ChamfFinRad(keyID) + (1-pow(t/stemLayers, 3))*1;
//Stem Exponent
///----- KEY Builder Module
module keycap(keyID = 0, cutLen = 0, visualizeDish = false, rossSection = false, Dish = true, Stem = false, homeDot = false) {
//Set Parameters for dish shape
FrontPath = quantize_trajectories(FrontTrajectory(keyID), steps = stepsize, loop=false, start_position= $t*4);
BackPath = quantize_trajectories(BackTrajectory(keyID), steps = stepsize, loop=false, start_position= $t*4);
//Scaling initial and final dim tranformation by exponents
function FrontDishArc(t) = pow((t)/(len(FrontPath)),FrontArcExpo(keyID))*FrontFinArc(keyID) + (1-pow(t/(len(FrontPath)),FrontArcExpo(keyID)))*FrontInitArc(keyID);
function BackDishArc(t) = pow((t)/(len(FrontPath)),BackArcExpo(keyID))*BackFinArc(keyID) + (1-pow(t/(len(FrontPath)),BackArcExpo(keyID)))*BackInitArc(keyID);
FrontCurve = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(DishDepth(keyID), FrontDishArc(i), 1, d = 0)) ];
BackCurve = [ for(i=[0:len(BackPath)-1]) transform(BackPath[i], DishShape(DishDepth(keyID), BackDishArc(i), 1, d = 0)) ];
//builds
difference(){
union(){
difference(){
skin([for (i=[0:layers-1]) transform(translation(CapTranslation(i, keyID)) * rotation(CapRotation(i, keyID)), rounded_rectangle_profile(CapTransform(i, keyID),fn=fn,r=CapRadius(i, keyID)))]); //outer shell
//Cut inner shell
if(Stem == true){
translate([0,0,-.001])skin([for (i=[0:layers-1]) transform(translation(InnerTranslation(i, keyID)) * rotation(CapRotation(i, keyID)), rounded_rectangle_profile(InnerTransform(i, keyID),fn=fn,r=CapRadius(i, keyID)))]);
}
}
if(Stem == true){
rotate([0,0,stemRot])cherry_stem(KeyHeight(keyID), slop); // generate mx cherry stem, not compatible with box
translate([0,0,-.001])skin([for (i=[0:stemLayers-1]) transform(translation(StemTranslation(i,keyID))*rotation(StemRotation(i, keyID)), rounded_rectangle_profile(StemTransform(i, keyID),fn=fn,r=StemRadius(i, keyID)))]); //outer shell
}
//cut for fonts and extra pattern for light?
}
//Cuts
//Fonts
if(Legends == true){
// #rotate([-XAngleSkew(keyID),YAngleSkew(keyID),ZAngleSkew(keyID)])translate([0,4,KeyHeight(keyID)-2.5])linear_extrude(height = 0.5)text( text = "Why?", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
// #rotate([-XAngleSkew(keyID),YAngleSkew(keyID),ZAngleSkew(keyID)])translate([0,-3.5,0])linear_extrude(height = 0.5)text( text = "Me", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
}
//Dish Shape
if(Dish == true){
if(visualizeDish == false){
translate([-TopWidShift(keyID),.00001-TopLenShift(keyID),KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90+XAngleSkew(keyID),90-ZAngleSkew(keyID)])skin(FrontCurve);
translate([-TopWidShift(keyID),-TopLenShift(keyID),KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90-XAngleSkew(keyID),270-ZAngleSkew(keyID)])skin(BackCurve);
} else {
#translate([-TopWidShift(keyID),.00001-TopLenShift(keyID),KeyHeight(keyID)-DishHeightDif(keyID)]) rotate([0,-YAngleSkew(keyID),0])rotate([0,-90+XAngleSkew(keyID),90-ZAngleSkew(keyID)])skin(FrontCurve);
#translate([-TopWidShift(keyID),-TopLenShift(keyID),KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90-XAngleSkew(keyID),270-ZAngleSkew(keyID)])skin(BackCurve);
}
}
if(crossSection == true) {
translate([0,-15,-.1])cube([15,30,15]);
}
//Choc keyhole
#translate(ChocLoc)rotate(ChocAng)Keyhole(.1, clipLength = -3, cutThickness = 0);
}
//Homing dot
if(homeDot == true)translate([0,0,KeyHeight(keyID)-DishHeightDif(keyID)-.25])sphere(d = 1);
//choc support
translate(ChocLoc)rotate(ChocAng)translate([0,-2,.5,])cube([16,11,2],center = true);
}
//------------------stems
$fn = fn;
function outer_cherry_stem(slop) = [ stemWid - slop * 2, stemLen - slop * 2];
function outer_cherry_stabilizer_stem(slop) = [4.85 - slop * 2, 6.05 - slop * 2];
function outer_box_cherry_stem(slop) = [6 - slop, 6 - slop];
// .005 purely for aesthetics, to get rid of that ugly crosshatch
function cherry_cross(slop, extra_vertical = 0) = [
// horizontal tine
[4.03 + slop, 1.15 + slop / 3],
// vertical tine
[1.25 + slop / 3, 4.23 + extra_vertical + slop / 3 + .005],
];
module inside_cherry_cross(slop) {
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = stemCrossHeight) {
square(cherry_cross(slop, extra_vertical)[0], center=true);
square(cherry_cross(slop, extra_vertical)[1], center=true);
}
}
// Guides to assist insertion and mitigate first layer squishing
{
for (i = cherry_cross(slop, extra_vertical)) hull() {
linear_extrude(height = 0.01, center = false) offset(delta = 0.4) square(i, center=true);
translate([0, 0, 0.5]) linear_extrude(height = 0.01, center = false) square(i, center=true);
}
}
}
module cherry_stem(depth, slop) {
difference(){
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square(outer_cherry_stem(slop) - [2,2], center=true);
}
}
inside_cherry_cross(slop);
}
}
/// ----- helper functions
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, fn) * [size[0]/2-r,0]
+ sign_y(index, fn) * [0,size[1]/2-r]
];
function sign_x(i,n) =
i < n/4 || i > n-n/4 ? 1 :
i > n/4 && i < n-n/4 ? -1 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;

View file

@ -1,328 +0,0 @@
use <scad-utils/morphology.scad> //for cheaper minwoski
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <sweep.scad>
use <skin.scad>
//TODO add shift
keycap(keyID = 7, cutLen = 0, Stem =true, Dish = true, visualizeDish = true, crossSection = false, homeDot = false);
////fullset
//for(Row = [0:4]){
// for(Col = [0:5]){
// translate([20*Col, 20*Row, 0])keycap(keyID = Col*5+Row, cutLen = 0, Stem =false, Dish = true, visualizeDish = false, crossSection = false);
// }
//}
//Parameters
wallthickness = 1.75;
topthickness = 2.25;
stepsize = 50; //resolution of Trajectory
step = 2; //resolution of ellipes
fn = 60; //resolution of Rounded Rectangles: 60 for output
layers = 50; //resolution of vertical Sweep: 50 for output
keyParameters = //keyParameters[KeyID][ParameterID]
[
// BotWid, BotLen, TWDif, TLDif, keyh, WSft, LSft XSkew, YSkew, ZSkew, WEx, LEx, CapRIn, CapRFn, CapREx
//Column 0
[18.16, 18.16, 6, 6, 10, 0, 0, -13, -5, -12, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6, 8+4, 0, 0, 5, -10, 10, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6, 7+4, 0, 0, -2, -10, 5, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6, 8+4, 0, 0, -7, -10, -5, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11+4, 0, 0, -13, -10, -10, 2, 2, .2, 3, 1], //R1 4
//Column 1
[18.16, 18.16, 6, 6, 10, 0, 0, -13, 5, 12, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6, 8+2, 0, 0, 5, -3, 0, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6, 7+2, 0, 0, -2, -3, 0, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6, 8+2, 0, 0, -7, -3, 0, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11+2, 0, 0, -13, -3, 0, 2, 2, .2, 3, 1], //R1 9
//Column 2 middle
[18.16, 18.16, 6, 6, 12, 0, 0, -13, 10, 15, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6, 8, 0, 0, 5, 0, 0, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6, 7, 0, 0, -2, 0, 0, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6, 8, 0, 0, -7, 0, 0, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11, 0, 0, -13, 0, 0, 2, 2, .2, 3, 1], //R1
//Column 3
[18.16, 18.16, 6, 6, 11+3, 0, 0, 13, -4, 0, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6, 8+3, 0, 0, 5, -4, 0, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6, 7+3, 0, 0, -2, -4, 0, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6, 8+3, 0, 0, -7, -4, 0, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11+3, 0, 0, -13, -4, 0, 2, 2, .2, 3, 1], //R1
//Column 4
[18.16, 18.16, 6, 6,11+5.5, 0, 0, 13, -10, 0, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6,8+5.5, 0, 0, 5, -10, 0, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6,7+5.5, 0, 0, -2, -10, 0, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6,8+5.5, 0, 0, -7, -10, 0, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11+3, 0, 0, -13, 10, 0, 2, 2, .2, 3, 1], //R1
//Column 5
[18.16, 18.16, 6, 6, 11+4, 0, 0, 13, -6, 0, 2, 2, .2, 3, 1], //R5
[18.16, 18.16, 6, 6, 8+4, 0, 0, 5, -6, 0, 2, 2, .2, 3, 1], //R4
[18.16, 18.16, 6, 6, 7+4, 0, 0, -2, -6, 0, 2, 2, .2, 3, 1], //R3 Home
[18.16, 18.16, 6, 6, 8+4, 0, 0, -7, -6, 0, 2, 2, .2, 3, 1], //R2
[18.16, 18.16, 6, 6, 11+5, 0, 0, -13, 10, 0, 2, 2, .2, 3, 1], //R1
];
function BottomWidth(keyID) = keyParameters[keyID][0]; //
function BottomLength(keyID) = keyParameters[keyID][1]; //
function TopWidthDiff(keyID) = keyParameters[keyID][2]; //
function TopLenDiff(keyID) = keyParameters[keyID][3]; //
function KeyHeight(keyID) = keyParameters[keyID][4]; //
function TopWidShift(keyID) = keyParameters[keyID][5];
function TopLenShift(keyID) = keyParameters[keyID][6];
function XAngleSkew(keyID) = keyParameters[keyID][7];
function YAngleSkew(keyID) = keyParameters[keyID][8];
function ZAngleSkew(keyID) = keyParameters[keyID][9];
function WidExponent(keyID) = keyParameters[keyID][10];
function LenExponent(keyID) = keyParameters[keyID][11];
function ChamfInitRad(keyID) = keyParameters[keyID][12];
function ChamfFinRad(keyID) = keyParameters[keyID][13];
function ChamExponent(keyID) = keyParameters[keyID][14];
dishParameters = //dishParameter[keyID][ParameterID]
[
//FFwd1 FFwd2 FPit1 FPit2 DshDep DshHDif FArcIn FArcFn FArcEx BFwd1 BFwd2 BPit1 BPit2 BArcIn BArcFn BArcEx
//Column 0
[ 5, 3, 5.8, -42, 3.5, 1.5, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 18, 2], //R5
[ 6, 3, 15, -50, 3.5, 1.5, 8.5, 19, 2, 5, 4, 13, -50, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 4, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.6, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.7, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 18, 2], //R1
//Column 1
[ 5, 3.5, 5, -48, 3.5, 1.5, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 9, 15, 2, 5, 4, 13, -30, 9, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R1
//Column 2
[ 5, 3.5, 5, -48, 3.5, 1.7, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 18, 2], //R5
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R1
//Column 3
[ 5, 3, 5, -50, 3.5, 1.5, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 3.5, 1.6, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 4, 1.6, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R1
//Column 4
[ 5, 3, 5, -50, 3.5, 1.6, 8.6, 12, 2, 6, 4, 13, -30, 8.6, 16, 2], //R5
[ 6, 3, 18, -50, 3.5, 1.6, 8.5, 17, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 4, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.6, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.6, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R1
//Column 5
[ 5, 3, 5, -50, 3.5, 1.5, 8.5, 10, 2, 6, 4, 13, -30, 8.5, 16, 2], //R5
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R4
[ 6, 3, 18, -50, 5, 1.7, 8.5, 15, 2, 5, 4, 13, -30, 8.5, 16, 2], //R3
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2], //R2
[ 6, 3, 18, -50, 3.5, 1.5, 8.5, 15, 2, 6, 4, 13, -30, 8.5, 16, 2] //R1
];
function FrontForward1(keyID) = dishParameters[keyID][0]; //
function FrontForward2(keyID) = dishParameters[keyID][1]; //
function FrontPitch1(keyID) = dishParameters[keyID][2]; //
function FrontPitch2(keyID) = dishParameters[keyID][3]; //
function DishDepth(keyID) = dishParameters[keyID][4]; //
function DishHeightDif(keyID) = dishParameters[keyID][5]; //
function FrontInitArc(keyID) = dishParameters[keyID][6];
function FrontFinArc(keyID) = dishParameters[keyID][7];
function FrontArcExpo(keyID) = dishParameters[keyID][8];
function BackForward1(keyID) = dishParameters[keyID][9]; //
function BackForward2(keyID) = dishParameters[keyID][10]; //
function BackPitch1(keyID) = dishParameters[keyID][11]; //
function BackPitch2(keyID) = dishParameters[keyID][12]; //
function BackInitArc(keyID) = dishParameters[keyID][13];
function BackFinArc(keyID) = dishParameters[keyID][14];
function BackArcExpo(keyID) = dishParameters[keyID][15];
function FrontTrajectory(keyID) =
[
trajectory(forward = FrontForward1(keyID), pitch = FrontPitch1(keyID)), //more param available: yaw, roll, scale
trajectory(forward = FrontForward2(keyID), pitch = FrontPitch2(keyID)) //You can add more traj if you wish
];
function BackTrajectory (keyID) =
[
trajectory(forward = BackForward1(keyID), pitch = BackPitch1(keyID)),
trajectory(forward = BackForward2(keyID), pitch = BackPitch2(keyID)),
];
//------- function defining Dish Shapes
function ellipse(a, b, d = 0, rot1 = 0, rot2 = 360) = [for (t = [rot1:step:rot2]) [a*cos(t)+a, b*sin(t)*(1+d*cos(t))]]; //Centered at a apex to avoid inverted face
function DishShape (a,b,c,d) =
concat(
// [[c+a,b]],
ellipse(a, b, d = 0,rot1 = 90, rot2 = 270)
// [[c+a,-b]]
);
function oval_path(theta, phi, a, b, c, deform = 0) = [
a*cos(theta)*cos(phi), //x
c*sin(theta)*(1+deform*cos(theta)) , //
b*sin(phi),
];
path_trans2 = [for (t=[0:step:180]) translation(oval_path(t,0,10,15,2,0))*rotation([0,90,0])];
//--------------Function definng Cap
function CapTranslation(t, keyID) =
[
((1-t)/layers*TopWidShift(keyID)), //X shift
((1-t)/layers*TopLenShift(keyID)), //Y shift
(t/layers*KeyHeight(keyID)) //Z shift
];
function InnerTranslation(t, keyID) =
[
((1-t)/layers*TopWidShift(keyID)), //X shift
((1-t)/layers*TopLenShift(keyID)), //Y shift
(t/layers*(KeyHeight(keyID)-topthickness)) //Z shift
];
function CapRotation(t, keyID) =
[
((1-t)/layers*XAngleSkew(keyID)), //X shift
((1-t)/layers*YAngleSkew(keyID)), //Y shift
((1-t)/layers*ZAngleSkew(keyID)) //Z shift
];
function CapTransform(t, keyID) =
[
pow(t/layers, WidExponent(keyID))*(BottomWidth(keyID) -TopLenDiff(keyID)) + (1-pow(t/layers, WidExponent(keyID)))*BottomWidth(keyID) ,
pow(t/layers, LenExponent(keyID))*(BottomLength(keyID)-TopLenDiff(keyID)) + (1-pow(t/layers, LenExponent(keyID)))*BottomLength(keyID)
];
function InnerTransform(t, keyID) =
[
pow(t/layers, WidExponent(keyID))*(BottomWidth(keyID) -TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/layers, WidExponent(keyID)))*(BottomWidth(keyID) -wallthickness*2),
pow(t/layers, LenExponent(keyID))*(BottomLength(keyID)-TopLenDiff(keyID)-wallthickness*2) + (1-pow(t/layers, LenExponent(keyID)))*(BottomLength(keyID)-wallthickness*2)
];
function CapRadius(t, keyID) = pow(t/layers, keyParameters[keyID][14])*keyParameters[keyID][13] + (1-pow(t/layers, keyParameters[keyID][14]))*keyParameters[keyID][12];
///----- KEY Builder Module
module keycap(keyID = 0, cutLen = 0, visualizeDish = false, rossSection = false, Dish = true, Stem = false, homeDot = false) {
//Set Parameters for dish shape
FrontPath = quantize_trajectories(FrontTrajectory(keyID), steps = stepsize, loop=false, start_position= $t*4);
BackPath = quantize_trajectories(BackTrajectory(keyID), steps = stepsize, loop=false, start_position= $t*4);
//Scaling initial and final dim tranformation by exponents
function FrontDishArc(t) = pow((t)/(len(FrontPath)),FrontArcExpo(keyID))*FrontFinArc(keyID) + (1-pow(t/(len(FrontPath)),FrontArcExpo(keyID)))*FrontInitArc(keyID);
function BackDishArc(t) = pow((t)/(len(FrontPath)),BackArcExpo(keyID))*BackFinArc(keyID) + (1-pow(t/(len(FrontPath)),BackArcExpo(keyID)))*BackInitArc(keyID);
FrontCurve = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(DishDepth(keyID), FrontDishArc(i), 1, d = 0)) ];
BackCurve = [ for(i=[0:len(BackPath)-1]) transform(BackPath[i], DishShape(DishDepth(keyID), BackDishArc(i), 1, d = 0)) ];
difference(){
union(){
difference(){
skin([for (i=[0:layers-1]) transform(translation(CapTranslation(i, keyID)) * rotation(CapRotation(i, keyID)), rounded_rectangle_profile(CapTransform(i, keyID),fn=fn,r=CapRadius(i, keyID)))]);
//Cut inner
if(Stem == true){
translate([0,0,-.001])skin([for (i=[0:layers-1]) transform(translation(InnerTranslation(i, keyID)) * rotation(CapRotation(i, keyID)), rounded_rectangle_profile(InnerTransform(i, keyID),fn=fn,r=CapRadius(i, keyID)))]);
}
}
if(Stem == true)rotate([0,0,stemRot])cherry_stem(KeyHeight(keyID), slop);
//cut for fonts and extra pattern for light?
}
//Cuts
//Fonts
// #rotate([-XAngleSkew(keyID),YAngleSkew(keyID),ZAngleSkew(keyID)])translate([0,4,KeyHeight(keyID)-2.5])linear_extrude(height = 0.5)text( text = "Why?", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
// #rotate([-XAngleSkew(keyID),YAngleSkew(keyID),ZAngleSkew(keyID)])translate([0,-3.5,0])linear_extrude(height = 0.5)text( text = "Me", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
//Dish Shape
if(Dish == true){
if(visualizeDish == false){
translate([0,.00001,KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90+XAngleSkew(keyID),90-ZAngleSkew(keyID)])skin(FrontCurve);
translate([0,0,KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90-XAngleSkew(keyID),270-ZAngleSkew(keyID)])skin(BackCurve);
} else {
#translate([0,.00001,KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90+XAngleSkew(keyID),90-ZAngleSkew(keyID)])skin(FrontCurve);
#translate([0,0,KeyHeight(keyID)-DishHeightDif(keyID)])rotate([0,-YAngleSkew(keyID),0])rotate([0,-90-XAngleSkew(keyID),270-ZAngleSkew(keyID)])skin(BackCurve);
}
}
if(crossSection == true) {
translate([0,-15,-.1])cube([15,30,15]);
}
}
//Homing dot
if(homeDot == true)translate([0,0,KeyHeight(keyID)-DishHeightDif(keyID)-.25])sphere(d = 1);
}
//------------------stems
$fn = 32;
slop = 0.3;
stemRot = 0;
extra_vertical = 0.6;
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
function outer_cherry_stabilizer_stem(slop) = [4.85 - slop * 2, 6.05 - slop * 2];
function outer_box_cherry_stem(slop) = [6 - slop, 6 - slop];
// .005 purely for aesthetics, to get rid of that ugly crosshatch
function cherry_cross(slop, extra_vertical = 0) = [
// horizontal tine
[4.03 + slop, 1.15 + slop / 3],
// vertical tine
[1.25 + slop / 3, 4.23 + extra_vertical + slop / 3 + .005],
];
module inside_cherry_cross(slop) {
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = 4) {
square(cherry_cross(slop, extra_vertical)[0], center=true);
square(cherry_cross(slop, extra_vertical)[1], center=true);
}
}
// Guides to assist insertion and mitigate first layer squishing
{
for (i = cherry_cross(slop, extra_vertical)) hull() {
linear_extrude(height = 0.01, center = false) offset(delta = 0.4) square(i, center=true);
translate([0, 0, 0.5]) linear_extrude(height = 0.01, center = false) square(i, center=true);
}
}
}
module cherry_stem(depth, slop) {
difference(){
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square(outer_cherry_stem(slop) - [2,2], center=true);
}
}
inside_cherry_cross(slop);
}
}
/// ----- helper functions
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, fn) * [size[0]/2-r,0]
+ sign_y(index, fn) * [0,size[1]/2-r]
];
function sign_x(i,n) =
i < n/4 || i > n-n/4 ? 1 :
i > n/4 && i < n-n/4 ? -1 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;

View file

@ -1,186 +0,0 @@
use <scad-utils/morphology.scad> //for cheaper minwoski
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <scad-utils/trajectory.scad>
use <scad-utils/trajectory_path.scad>
use <sweep.scad>
use <skin.scad>
use <Switch.scad>
//TODO: Make Alias for key[n]
wallthickness = 2.5;
topthickness = 3.0;
key =
//[
// BotWid, BotLen, TopWDif, TopLDif, height, WShift, LShift XAngSkew, YAngSkew, ZAngSkew LExpo, WExpo, CapRadIn, CapRadFn, CapRadExpd
[18.16*1.25, 18.16, 5, 5, 13, 0, 0, -6, -5, 0, 2.5, 2.5, .2, 3, 2];
//];
step = 2;
function ellipse(a, b, d = 0, rot1 = 0, rot2 = 360) = [for (t = [rot1:step:rot2]) [a*cos(t)+a, b*sin(t)*(1+d*cos(t))]]; //Centered at a apex to avoid inverted face
function DishShape (a,b,c,d) =
concat(
// [[c+a,b]],
ellipse(a, b, d = 0,rot1 = 90, rot2 = 270)
// [[c+a,-b]]
);
function oval_path(theta, phi, a, b, c, deform = 0) = [
a*cos(theta)*cos(phi), //x
c*sin(theta)*(1+deform*cos(theta)) , //
b*sin(phi),
];
path_trans2 = [for (t=[0:step:180]) translation(oval_path(t,0,10,15,2,0))*rotation([0,90,0])];
//------------Define the trajectory of the dish shsape cuts
FrontTraj = [
trajectory(forward = 6, pitch = 12),
trajectory(forward = 3, pitch = -50)
];
BackTraj = [
trajectory(forward = 6, pitch = 10),
trajectory(forward = 4, pitch = -30),
// trajectory(forward = 10, pitch = -20, roll = 0)
];
//quantized trajectory to be fed into transform
stepsize = 50;
fn=60;
FrontPath = quantize_trajectories(FrontTraj, steps = stepsize, loop=false, start_position= $t*4);
BackPath = quantize_trajectories(BackTraj, steps = stepsize, loop=false, start_position= $t*4);
FrontCurve = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(2.5, 12, 1, d = 0)) ];
BackCurve = [ for(i=[0:len(BackPath)-1]) transform(BackPath[i], DishShape(2.5, 12, 1, d = 0)) ];
FrontCurve2 = [ for(i=[0:len(FrontPath)-1]) transform(FrontPath[i], DishShape(2+2, 10+2, 2, d = 0)) ];
//--------------For Cap
layers = 50;
function CapTranslation(t) =
[
((1-t)/layers*key[5]), //X shift
((1-t)/layers*key[6]), //Y shift
(t/layers*key[4]) //Z shift
];
function InnerTranslation(t) =
[
((1-t)/layers*key[5]), //X shift
((1-t)/layers*key[6]), //Y shift
(t/layers*(key[4]-topthickness)) //Z shift
];
function CapRotation(t) =
[
((1-t)/layers*key[7]), //X shift
((1-t)/layers*key[8]), //Y shift
((1-t)/layers*key[9]) //Z shift
];
function CapTransform(t) =
[
pow(t/layers, key[10])*(key[0]-key[2]) + (1-pow(t/layers, key[10]))*key[0],
pow(t/layers, key[11])*(key[1]-key[3]) + (1-pow(t/layers, key[11]))*key[1]
];
function InnerTransform(t) =
[
pow(t/layers, key[10])*(key[0]-key[2]-wallthickness) + (1-pow(t/layers, key[10]))*(key[0]-wallthickness),
pow(t/layers, key[11])*(key[1]-key[3]-wallthickness) + (1-pow(t/layers, key[11]))*(key[1]-wallthickness)
];
function CapRadius(t) = pow(t/layers, key[14])*key[13] + (1-pow(t/layers, key[14]))*key[12];
///KEY Build
difference(){
union(){
difference(){
skin([for (i=[0:layers-1])transform(translation(CapTranslation(i)) * rotation(CapRotation(i)), rounded_rectangle_profile(CapTransform(i),fn=fn,r=CapRadius(i)))]);
//use intersection with stem here?
translate([0,0,-.001])skin([for (i=[0:layers-1])transform(translation(InnerTranslation(i)) * rotation(CapRotation(i)), rounded_rectangle_profile(InnerTransform(i),fn=fn,r=CapRadius(i)))]);
}
rotate([0,0,stemRot])cherry_stem(10, slop);
//cut for fonts and extra pattern for light?
}
// #rotate([-key[7],key[8],key[9]])translate([0,4,key[4]-2.5])linear_extrude(height = 0.5)text( text = "Why?", font = "Constantia:style=Bold", size = 3, valign = "center", halign = "center" );
translate([0,.00001,key[4]-1.5])rotate([0,-key[8],0])rotate([0,-90+key[7],90-key[9]])skin(FrontCurve);
translate([0,0,key[4]-1.5])rotate([0,-key[8],0])rotate([0,-90-key[7],270-key[9]])skin(BackCurve);
#translate([0,-6.6,7.8])rotate([72,0,0])Keyhole(.1, clipLength = -3, cutThickness = 0);
// translate([0,0,-.1])cube([15,15,15]);
}
//------------------stems
$fn = 32;
slop = 0.3;
stemRot = 0;
extra_vertical = 0.6;
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
function outer_cherry_stabilizer_stem(slop) = [4.85 - slop * 2, 6.05 - slop * 2];
function outer_box_cherry_stem(slop) = [6 - slop, 6 - slop];
// .005 purely for aesthetics, to get rid of that ugly crosshatch
function cherry_cross(slop, extra_vertical = 0) = [
// horizontal tine
[4.03 + slop, 1.15 + slop / 3],
// vertical tine
[1.25 + slop / 3, 4.23 + extra_vertical + slop / 3 + .005],
];
module inside_cherry_cross(slop) {
// inside cross
// translation purely for aesthetic purposes, to get rid of that awful lattice
translate([0,0,-0.005]) {
linear_extrude(height = 4) {
square(cherry_cross(slop, extra_vertical)[0], center=true);
square(cherry_cross(slop, extra_vertical)[1], center=true);
}
}
// Guides to assist insertion and mitigate first layer squishing
{
for (i = cherry_cross(slop, extra_vertical)) hull() {
linear_extrude(height = 0.01, center = false) offset(delta = 0.4) square(i, center=true);
translate([0, 0, 0.5]) linear_extrude(height = 0.01, center = false) square(i, center=true);
}
}
}
module cherry_stem(depth, slop) {
difference(){
// outside shape
linear_extrude(height = depth) {
offset(r=1){
square(outer_cherry_stem(slop) - [2,2], center=true);
}
}
inside_cherry_cross(slop);
}
}
/// ----- helper functions
function rounded_rectangle_profile(size=[1,1],r=1,fn=32) = [
for (index = [0:fn-1])
let(a = index/fn*360)
r * [cos(a), sin(a)]
+ sign_x(index, fn) * [size[0]/2-r,0]
+ sign_y(index, fn) * [0,size[1]/2-r]
];
function sign_x(i,n) =
i < n/4 || i > n-n/4 ? 1 :
i > n/4 && i < n-n/4 ? -1 :
0;
function sign_y(i,n) =
i > 0 && i < n/2 ? 1 :
i > n/2 ? -1 :
0;

View file

@ -1,142 +0,0 @@
plate_thickness = 1;
plate_size = 15.6;
edge_offset = 1;
bottom_height = 5;
bottom_size = plate_size - 2;
top_height = 11.6;
switch_height = 3.0;
switch_thick = 1;
switch_width = 5;
switch_length = 3;
cap_height = .38*25.4;
cap_heightShift = 0.69*25.4;
cap_width = 18.3;
clip_Length = 3; // length clipped
//dummy key switch with caps to check position
module Switch(switchScale= [1,1,1], colors = "teal", clipLength = 0, type = "")
{
difference(){
union(){
translate([0,0,1.75]){
difference(){
translate([0,0,0.5])cube([15,15,1], center = true);
//cuts
// translate([15/2-1/2,0,.5])cube([1,10.5,2], center = true);
// translate([-15/2+1/2,0,.5])cube([1,10.5,2], center = true);
}
translate([0,0,1.5])cube([13,13,2], center = true);
color("springGreen")translate([0,0,4])cube([11.4,4,3], center = true);
color("springGreen")translate([0,1,4])cube([3,5,3], center = true);
color("DarkSlateGray")translate([0,0,-1])cube([13,14,2,],center = true);
color("DarkSlateGray")translate([0,0,-2-2.5])cylinder(d=3.3, 2.5);
color("DarkSlateGray")translate([5,0,-2-2.5])cylinder(d=1.6, 2.5);
color("DarkSlateGray")translate([-5,0,-2-2.5])cylinder(d=1.6, 2.5);
//cap
color("ivory")hull(){
translate([0,0,4.5+1])cube([17.5,16.8,2],center = true);
translate([0,1.25,4.5+1+1.5])cube([14.5,12.5,1.5],center = true);
}
}
}
if (clipLength != 0){ // commiting unholy act in name of ergonomics
translate([0, -sign(clipLength)*7.8-clipLength, 0])cube([20, 15.6, 40], center = true);
}
}
}
module Cutter()
{
bottom_height = 4.5;
bottom_chamfer_width = 3;
bottom_chamfer_height = 1;
bottom_chamfer_thickness = .6;
bottom_peg_diameter = 4;
bottom_peg_height = 3;
bottom_peg_chamfer = 1;
bottom_peg_side_scale = 1.7/4;
translate([-bottom_size/2, -bottom_size/2 ,0])cube([bottom_size,bottom_size,bottom_height]);
translate([0,0, -(bottom_peg_height -bottom_peg_chamfer)]){
cylinder(d=bottom_peg_diameter, h= bottom_peg_height -bottom_peg_chamfer);
translate([5,0,0])scale(v=[bottom_peg_side_scale,bottom_peg_side_scale,1])cylinder(d=bottom_peg_diameter, h= bottom_peg_height -bottom_peg_chamfer);
translate([-5,0,0])scale(v=[bottom_peg_side_scale,bottom_peg_side_scale,1])cylinder(d=bottom_peg_diameter, h= bottom_peg_height -bottom_peg_chamfer);
translate([0,0, -bottom_peg_chamfer]){
cylinder(d2=bottom_peg_diameter , d1 = bottom_peg_diameter -2*bottom_peg_chamfer, h= bottom_peg_chamfer);
translate([5,0,0])scale(v=[bottom_peg_side_scale,bottom_peg_side_scale,1])cylinder(d2=bottom_peg_diameter , d1 = bottom_peg_diameter -2*bottom_peg_chamfer, h= bottom_peg_chamfer);
translate([-5,0,0])scale(v=[bottom_peg_side_scale,bottom_peg_side_scale,1])cylinder(d2=bottom_peg_diameter , d1 = bottom_peg_diameter -2*bottom_peg_chamfer, h= bottom_peg_chamfer);
}
}
}
//MX series keyhole
// TODO: add alps support?
module Keyhole(tol = .1, cutThickness = .5, clipLength = 0)
{
$fn = 10;
bottom_length = 13.9+tol;
plate_thickness = 3.51; //mm
holeLength = bottom_length+tol*2;
//latch nibs
nib_radius= 1;
nib_length = 3;
translate([0,0,-1.25])difference(){
union(){
translate([0,0,1.25])cube([holeLength, holeLength, plate_thickness+tol], center =true);
// translate([0,0,.25-cutThickness/2])cube([holeLength+1, holeLength+1, plate_thickness+cutThickness], center =true);
}
union(){
if (clipLength != 0){
translate([0, -sign(clipLength)*7.8-clipLength, 0])cube([20, 15.6, 40], center = true);
}
}
}
}
module Stabilizer(offsets = 23.8/2)
{
plate_thickness = 3.6; //mm
stabilizer_width = 5;
stabilizer_length = 12.2;
translate([offsets,0,0])cube([stabilizer_width,stabilizer_length,plate_thickness], center = true);
translate([-offsets,0,0])cube([stabilizer_width,stabilizer_length,plate_thickness], center = true);
}
module TrackPoint(nibLength = 20)
{
color("red")translate([0,0,-.5])cube([4.5,4.5,5], center= true); //nib
color("gold")cylinder(d = 2, nibLength); //nib
color("gold")translate([0,0,nibLength])sphere(2); //nib
translate([0,30.3/2-8,-3/2])cube([26.46, 30.3, 3], center = true);
}
module RotaryEncoder(stemLength = 13, Wheel = 0)
{
color("grey")translate([0,0, -6.1/2])cube([11.5, 13.5, 6.1], center = true);
cylinder(d = 7, 7.8);
translate([0,0,7.8])difference(){
cylinder(d = 5.8, stemLength);
translate([-5.8/2,5.8/2-1.5,3])cube([11.5, 13.5, stemLength]);
}
color("grey")translate([0,0,7.8])cylinder(d = Wheel, stemLength);
}
//################ Test Calls ###################
//Switch(clipLength = -4);
Keyhole(.1, clipLength = -4);
//Stabilizer(20);
// RotaryEncoder(Wheel = 0);
//Switch([1,1.5,1]);
//TrackPoint();