Update art and case

art to fit within 1mm boundary
case to be pretty
This commit is contained in:
William Toohey
2017-01-18 22:40:05 +10:00
parent ee18edecca
commit a2dff54bcf
14 changed files with 878 additions and 17 deletions
+2
View File
@@ -20,3 +20,5 @@ Hardware/Case/case.scad.*
Costs.xlsx
Hardware/Case/outputs/
Old/
Hardware/datasheets/
Hardware/Case/Laser Templates/
+12
View File
@@ -37,6 +37,18 @@ For tracks:
Cap: round
Path->Combine
Path->Stroke to path
For artwork:
Cross reference with altium to make layers for tracks
1.5mm
1.2mm
1mm
0.75mm
0.5mm
0.254mm
Raster Fill
Path->Combine each individual letter (todo: actually needed?)
Also do long lines in 0.75mm layer
You may need to Path->Union everything for artwork layers to render nicely
+1 -1
View File
@@ -2,6 +2,6 @@
SET scad="C:\Program Files\OpenSCAD\openscad.exe"
SET folder=outputs
for %%i in (art_trimmed,bottom_plate,bottom_ring,top_plate,top_ring) DO (
for %%i in (bottom_plate,bottom_ring,top_plate,top_ring,holes_internal,holes_surface) DO (
%scad% -o "%folder%\%%i.dxf" "%%i.scad"
)
+66 -15
View File
@@ -1,12 +1,17 @@
use <imports/cherry_mx.scad>
include <imports/mx_keycap.scad>
key_profile_index = 11;
$fn = 64;
switches = [[0,0],
[-42.862,-37.592],
[ 42.862,-37.592],
[-14.287,-37.592],
[ 14.287,-37.592],
[-28.5,-75.692],
[ 28.5,-75.692]];
// x, y, keycap width in units, isBlack
switches = [[0,0, 1],
[-42.862,-37.592, 1.25],
[ 42.862,-37.592, 1.25],
[-14.287,-37.592, 1.25],
[ 14.287,-37.592, 1.25],
[-28.5,-75.692, 1.75, 1],
[ 28.5,-75.692, 1.75, 1]];
bolts = [[30.025, 6.65],
[71, -16.925],
[71, 16.5],
@@ -21,8 +26,8 @@ encoderRadius = 13;
encoderHoles = [[71.6, 0.4, 3.4],
[69, -10.1, 1.6]];
switchHole = [0,-75.692];
switchDiam = 3;
macroHole = [0,-75.692];
macroDiam = 3;
usbWidth = 9;
usbPos = [-21.311, 10.3];
@@ -87,6 +92,22 @@ module switches() {
}
}
module switch_models() {
for(sw = switches) {
translate([sw[0], sw[1]])
cherry_mx_model();
}
}
module switch_keycaps() {
for(sw = switches) {
color(sw[3] ? [0.1,0.1,0.1] : [1,1,1])
translate([sw[0], sw[1], 11.5])
scale([sw[2],1,1])
key();
}
}
module bolt_spacers() {
for(bolt = bolts) {
translate([bolt[0], bolt[1]])
@@ -135,6 +156,22 @@ module encoderHoles_half() {
}
}
module encoder_model() {
translate([0,0,5.5])
rotate([90,0,0])
import("imports/PEC16.stl");
translate([0,0,13])
cylinder(20, d = 25);
}
module encoder_model_full() {
for(enc = encoders) {
translate([enc[0], enc[1]])
encoder_model();
}
}
// don't do the same thing twice
module usb_half() {
w = usbWidth / 2;
@@ -161,7 +198,7 @@ module usb() {
}
module board() {
import("BOARD_SHAPE.dxf");
import("imports/BOARD_SHAPE.dxf");
}
module board_encoderhole() {
@@ -180,8 +217,8 @@ module top_plate() {
}
switches();
bolts();
translate([switchHole[0], switchHole[1], 0])
circle(d = switchDiam, center = true);
translate([macroHole[0], macroHole[1], 0])
circle(d = macroDiam, center = true);
}
}
@@ -195,7 +232,7 @@ module top_ring() {
// Room for FX/START
switches();
};
import("RING_TOP_SUPPORTS.dxf");
import("imports/RING_TOP_SUPPORTS.dxf");
bolts_expansion();
}
bolt_spacers();
@@ -210,7 +247,7 @@ module pcb() {
}
module artwork() {
import("Artwork.dxf");
import("imports/Artwork.dxf");
}
module bottom_ring() {
@@ -221,7 +258,7 @@ module bottom_ring() {
offset(delta = -wallStrength)
board();
};
import("RING_BOT_SUPPORTS.dxf");
import("imports/RING_BOT_SUPPORTS.dxf");
bolts_expansion();
}
bolt_spacers();
@@ -264,7 +301,21 @@ module full_stack() {
color([1,1,1, 1])
linear_extrude(plate_thickness[2])
pcb();
// not-as-pretty model of macro key
translate([macroHole[0], macroHole[1], plate_thickness[2]])
color([1,0.5,0])
cylinder(h = 5.2, d = macroDiam);
translate([0, 0, plate_thickness[2] + boom]) {
// pretty models of stuff
translate([0, 0, boom*2]) {
color([0.8,0.8,0.8,1])
encoder_model_full();
switch_models();
switch_keycaps();
};
color([1, 1, 1, 0.4])
linear_extrude(plate_thickness[3])
top_ring();
+3
View File
@@ -0,0 +1,3 @@
use <case.scad>;
bolt_spacers();
@@ -1,3 +1,3 @@
use <case.scad>;
art_trimmed();
bolts();
Binary file not shown.
+123
View File
@@ -0,0 +1,123 @@
$fn=60;
/**
a cherry mx switch.
most of the measurements done with a caliper. some taken from
http://geekhack.org/index.php?topic=47744.0
This is just to illustrate and to drop in a a gross reference. It is mostly artistic apart from the steam and mounting plate dimensions
*/
module cherry_mx_model() {
translate([0,0,14.85])
{
//1. steam
color("brown"){
//1.1. l-r tab is 1.35mm
translate([0,0,-3.62/2])
cube([1.35,4.5,3.62], center=true);
//1.2. f-b tab is 1.15mm. it has a smal notch that i will ignore.
translate([0,0,-3.62/2])
cube([4.5,1.15,3.62], center=true);
//1.3. base. it has a chamfered top that i will ignore.
translate([0,0,-5.62])
cube([7.2,5.56,4], center=true);
}
// 2. top
color("grey"){
difference(){
// make a trapezoid with the general shape (volume?) of the top
hull(){
translate([0,0,-4]) //distance from top of switch... some i measured 3.9 others 4.2... so leaving at 4
cube([9.87,10.62,0.1], center=true);
translate([0,0,-4 -5.2]) // bottom has a measured 5.3... so move 5.2 and use the 0.1 bellow
cube([14.58,14.58,0.1], center=true);
}
// and subtract:
// the front led. NOTE: totally off... measured by eye. just for astetics
// adding just so there is a visual cue of the direction
translate([0,-4.7,-6])
cylinder(r=3/2, h=6, center=true);
translate([0,-5.5,-6])
cube([8,4,5], center=true);
// the four corners
// TODO waste of time? this is all for looks, you shouldn't invade any of that space anyway...
}
}
// 3. bottom
color("green")
// 3.1 main body volume
hull(){
translate([0,0,-4 -5.3]) //steam + top
cube([13.98,13.98,0.1], center=true);
translate([0,0,-4 -5.3 -2.2]) //steam + top + straigth part
cube([13.98,13.98,0.1], center=true);
translate([0,0,-4 -5.3 -5.5]) //steam + top + bottom (measured 5.5)
cube([12.74,13.6,0.1], center=true);
}
// 3.2 tabs
// note: only measured the lenght, if they are slightly off-center, this will be all wrong :)
color("black")
difference(){
translate([0,0,-4 -5.3 -0.82/2]) //steam + top
cube([15.64,15.64,0.82], center=true);
translate([0,0,-4 -5.3 -0.82/2 ]) // front-back cut
cube([5.64,20,0.82 +2], center=true);
translate([0,0,-4 -5.3 -0.82/2 ]) //side cut
cube([20,11.64,0.82 +2], center=true);
}
// 3.3 tab (plate snap on). to use this mechanically, you have to take into account the bending (as it will move the bottom part slightly up...) just for gross reference here for now
color("white"){
// 3.3.1 top
translate([0,0,-4 -5.3 -0.82/2 ]) // front-back cut
cube([1.82,16.33,0.82], center=true);
// 3.3.2 bottom
difference(){
hull(){
translate([0,0,-4 -5.3 -0.82/2 -1.76 ]) // front-back cut
cube([3.65,14,0.1], center=true);
translate([0,0,-4 -5.3 -0.82/2 -2.2 ]) // front-back cut
cube([3.65,14.74,0.1], center=true);
translate([0,0,-4 -5.3 -0.82/2 -2.89 ]) // front-back cut
cube([3.65,14,0.1], center=true);
}
translate([0,0,-4 -5.3 -0.82/2 -1.76 ]) // front-back cut
cube([2.2,20,4], center=true);
}
}
// 4. bottom guides
// again, i'm assuming everything is centered...
color("darkGreen"){
// 4.1 cylinder
translate([0,0,-4 -5.3 -5.5 -2/2]) //steam + top + bottom (measured 5.5)
cylinder(r=3.85/2, h=2, center=true);
translate([0,0,-4 -5.3 -5.5 -2 -1/2]) //steam + top + bottom (measured 5.5)
cylinder(r2=3.85/2, r=2.8/2, h=1, center=true);
// 4.2 PCB pins
translate([4.95,0,-4 -5.3 -5.5 -2/2]) //steam + top + bottom (measured 5.5)
cylinder(r=1.6/2, h=2, center=true);
translate([4.95,0,-4 -5.3 -5.5 -2 -1/2]) //steam + top + bottom (measured 5.5)
cylinder(r2=1.6/2, r=1/2, h=1, center=true);
translate([-4.95,0,-4 -5.3 -5.5 -2/2]) //steam + top + bottom (measured 5.5)
cylinder(r=1.6/2, h=2, center=true);
translate([-4.95,0,-4 -5.3 -5.5 -2 -1/2]) //steam + top + bottom (measured 5.5)
cylinder(r2=1.6/2, r=1/2, h=1, center=true);
}
// 5. pins
color("orange"){
translate([-3.77,2.7,-4 -5.3 -5.5 -3.1/2]) //steam + top + bottom (measured 5.5)
cube([.86, 0.2,3.1], center=true);
translate([2.7,5.2,-4 -5.3 -5.5 -3.1/2]) //steam + top + bottom (measured 5.5)
cube([.86, 0.2,3.1], center=true);
}
}
}
+670
View File
@@ -0,0 +1,670 @@
/* [Key] */
//length in units of key
key_length = 1;
//height in units of key. should remain 1 for most uses
key_height = 1;
//keycap type, [0:DCS Row 5, 1:DCS Row 1, 2:DCS Row 2, 3:DCS Row 3, 4:DCS Row 4, 5:DSA Row 3, 6:SA Row 1, 7:SA Row 2, 8:SA Row 3, 9:SA Row 4, 10:DCS Row 4 Spacebar, 11: g20 key (faked)]
key_profile_index = 0;
// keytop thickness, aka how many millimeters between the inside and outside of the top surface of the key
keytop_thickness = 1;
// wall thickness, aka the thickness of the sides of the keycap. note this is the total thickness, aka 3 = 1.5mm walls
wall_thickness = 3;
/* [Brim] */
//enable brim for connector
has_brim = 0;
//brim radius. 11 ensconces normal keycap stem in normal keycap
brim_radius = 11;
//brim depth
brim_depth = .3;
/* [Stabilizers] */
//whether stabilizer connectors are enabled
stabilizers = 0;
//stabilizer distance in mm
stabilizer_distance = 50;
/* [Dish] */
// invert dishing. mostly for spacebar
inverted_dish = 0;
/* [Stem] */
// cherry MX or Alps stem, or totally broken circular cherry stem [0..2]
stem_profile = 0;
// how inset the stem is from the bottom of the key. experimental. requires support
stem_inset = 0;
// stem offset in units NOT MM. for stepped caps lock
stem_offset = 0;
/* [Hidden] */
//change to round things better
$fn = 32;
//beginning to use unit instead of baked in 19.05
unit = 19.05;
//minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 default for faux G20
minkowski_radius = 1.75;
//profile specific stuff
/*
Here we have, for lack of a better implementation, an array
that defines the more intimate aspects of a key.
order is thus:
1. Bottom Key Width: width of the immediate bottom of the key
2. Bottom Key Height: height of the immediate bottom of the key
3. Top Key Width Difference: mm to subtract from bottom key width to create top key width
4. Top Key Height Difference: mm to subtract from bottom key height to create top key height
5. total Depth: how tall the total in the switch is before dishing
6. Top Tilt: X rotation of the top. Top and dish obj are rotated
7. Top Skew: Y skew of the top of the key relative to the bottom. DCS has some, DSA has none (its centered)
8. Dish Type: type of dishing. check out dish function for the options
9. Dish Depth: how many mm to cut into the key with
10. Dish Radius: radius of dish obj, the Sphere or Cylinder that cuts into the keycap
*/
key_profiles = [
//DCS Profile
[ //DCS ROW 5
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6, // Top Key Width Difference
4, // Top Key Height Difference
11.5, // total Depth
-6, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //DCS ROW 1
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6, // Top Key Width Difference
4, // Top Key Height Difference
8.5, // total Depth
-1, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //DCS ROW 2
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6.2, // Top Key Width Difference
4, // Top Key Height Difference
7.5, // total Depth
3, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //DCS ROW 3
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6, // Top Key Width Difference
4, // Top Key Height Difference
6.2, // total Depth
7, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //DCS ROW 4
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6, // Top Key Width Difference
4, // Top Key Height Difference
6.2, // total Depth
16, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
//DSA Profile
[ //DSA ROW 3
18.4, // Bottom Key Width
18.4, // Bottom Key Height
5.7, // Top Key Width Difference
5.7, // Top Key Height Difference
7.4, // total Depth
0, // Top Tilt
0, // Top Skew
//Dish Profile
1, // Dish Type
1.2, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
//SA Proile
[ //SA ROW 1
18.4, // Bottom Key Width
18.4, // Bottom Key Height
5.7, // Top Key Width Difference
5.7, // Top Key Height Difference
13.73, // total Depth, fudged
-14, // Top Tilt
0, // Top Skew
//Dish Profile
1, // Dish Type
1.2, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //SA ROW 2
18.4, // Bottom Key Width
18.4, // Bottom Key Height
5.7, // Top Key Width Difference
5.7, // Top Key Height Difference
11.73, // total Depth
-7, // Top Tilt
0, // Top Skew
//Dish Profile
1, // Dish Type
1.2, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //SA ROW 3
18.4, // Bottom Key Width
18.4, // Bottom Key Height
5.7, // Top Key Width Difference
5.7, // Top Key Height Difference
11.73, // total Depth
0, // Top Tilt
0, // Top Skew
//Dish Profile
1, // Dish Type
1.2, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //SA ROW 4
18.4, // Bottom Key Width
18.4, // Bottom Key Height
5.7, // Top Key Width Difference
5.7, // Top Key Height Difference
11.73, // total Depth
7, // Top Tilt
0, // Top Skew
//Dish Profile
1, // Dish Type
1.2, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //DCS ROW 4 SPACEBAR
18.16, // Bottom Key Width
18.16, // Bottom Key Height
6, // Top Key Width Difference
4, // Top Key Height Difference
6.2, // total Depth
16, // Top Tilt
1.75,// Top Skew
//Dish Profile
2, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //G20 AKA DCS Row 2 with no dish and shorter
18.16, // Bottom Key Width
18.16, // Bottom Key Height
2, // Top Key Width Difference
2, // Top Key Height Difference
6, // total Depth
2.5, // Top Tilt
0.75,// Top Skew
//Dish Profile
3, // Dish Type
0, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
[ //NONWORKING fake ISO enter
18.16 * 1.5, // Bottom Key Width
18.16 * 2, // Bottom Key Height
4, // Top Key Width Difference
4, // Top Key Height Difference
7, // total Depth
0, // Top Tilt
1.75,// Top Skew
//Dish Profile
0, // Dish Type
1, // Dish Depth
0, // Dish Skew X
0 // DIsh Skew Y
],
];
// derived variables
//key profile selected
key_profile = key_profiles[key_profile_index];
// names, so I don't go crazy
bottom_key_width = key_profile[0];
bottom_key_height = key_profile[1];
width_difference = key_profile[2];
height_difference = key_profile[3];
total_depth = key_profile[4];
top_tilt = key_profile[5] / key_height;
top_skew = key_profile[6];
dish_type = key_profile[7];
dish_depth = key_profile[8];
dish_skew_x = key_profile[9];
dish_skew_y = key_profile[10];
// actual mm key width and height
total_key_width = bottom_key_width + (unit * (key_length - 1));
total_key_height = bottom_key_height + (unit * (key_height - 1));
// actual mm key width and height at the top
top_total_key_width = bottom_key_width + (unit * (key_length - 1)) - width_difference;
top_total_key_height = bottom_key_height + (unit * (key_height - 1)) - height_difference;
//centered
module roundedRect(size, radius) {
x = size[0];
y = size[1];
z = size[2];
translate([-x/2,-y/2,0])
linear_extrude(height=z)
hull() {
translate([radius, radius, 0])
circle(r=radius);
translate([x - radius, radius, 0])
circle(r=radius);
translate([x - radius, y - radius, 0])
circle(r=radius);
translate([radius, y - radius, 0])
circle(r=radius);
}
}
// stem related stuff
// bottom we can use to anchor the stem, just a big ol cube with the inside of
// the keycap hollowed out
module inside(){
difference(){
translate([0,0,50]) cube([100000,100000,100000],center=true);
// NOTE: you're saying hey, if this is the inside why aren't we doing
// wall_thickness, keytop_thickness? well first off congratulations for
// figuring that out cuz it's a rat's nest in here. second off
// due to how the minkowski_key function works that isn't working out right
// now. it's a simple change if is_minkowski is implemented though
shape(0, 0);
}
}
module cherry_stem(){
// cross length
cross_length = 4.4;
//extra vertical cross length - the extra length of the up/down bar of the cross
extra_vertical_cross_length = 1.1;
//dimensions of connector
// outer cross extra length in x
extra_outer_cross_width = 2.10;
// outer cross extra length in y
extra_outer_cross_height = 1.0;
// dimensions of cross
// horizontal cross bar width
horizontal_cross_width = 1.4;
// vertical cross bar width
vertical_cross_width = 1.3;
// cross depth, stem height is 3.4mm
cross_depth = 4;
difference(){
union(){
if (stem_profile != 2){
translate([
-(cross_length+extra_outer_cross_width)/2,
-(cross_length+extra_outer_cross_height)/2,
stem_inset
])
cube([ // the base of the stem, the part the cruciform digs into
cross_length+extra_outer_cross_width,
cross_length+extra_outer_cross_height,
50
]);
} else {
cylinder(
d = cross_length+extra_outer_cross_height,
h = 50
);
}
if (has_brim == 1){ cylinder(r=brim_radius,h=brim_depth); }
}
//the cross part of the steam
translate([0,0,(cross_depth)/2 + stem_inset]){
cube([vertical_cross_width,cross_length+extra_vertical_cross_length,cross_depth], center=true );
cube([cross_length,horizontal_cross_width,cross_depth], center=true );
}
}
}
module alps_stem(){
cross_depth = 40;
width = 4.45;
height = 2.25;
base_width = 12;
base_height = 15;
translate([0,0,cross_depth/2 + stem_inset]){
cube([width,height,cross_depth], center = true);
}
}
//whole connector, alps or cherry, trimmed to fit
module connector(has_brim){
difference(){
//TODO can I really not do an array index here?
translate([-unit * stem_offset, 0, 0])
union(){
if(stem_profile == 0 || stem_profile == 2) cherry_stem();
if(stem_profile == 1) alps_stem();
}
inside();
}
}
//stabilizer connectors
module stabilizer_connectors(has_brim){
translate([stabilizer_distance,0,0]) connector(has_brim);
translate([-stabilizer_distance,0,0]) connector(has_brim);
}
//shape related stuff
//general shape of key. used for inside and outside
module shape(thickness_difference, depth_difference){
if (inverted_dish == 1){
difference(){
union(){
shape_hull(thickness_difference, depth_difference, 1);
dish(depth_difference);
}
outside(thickness_difference);
}
} else{
difference(){
shape_hull(thickness_difference, depth_difference, 1);
dish(depth_difference);
}
}
}
// conicalish clipping shape to trim things off the outside of the keycap
// literally just a key with height of 2 to make sure nothing goes awry with dishing etc
module outside(thickness_difference){
difference(){
cube([100000,100000,100000],center = true);
shape_hull(thickness_difference, 0, 2);
}
}
// super basic hull shape without dish
// modifier multiplies the height and top differences of the shape,
// which is only used for dishing to cut the dish off correctly
// height_difference used for keytop thickness
module shape_hull(thickness_difference, depth_difference, modifier){
hull(){
// bottom_key_width + (key_length -1) * unit is the correct length of the
// key. only 1u of the key should be bottom_key_width long; all others
// should be 1u
roundedRect([total_key_width - thickness_difference, total_key_height - thickness_difference, .001],1.5);
//height_difference outside of modifier because that doesnt make sense
translate([0,top_skew,total_depth * modifier - depth_difference])
rotate([-top_tilt,0,0])
roundedRect([total_key_width - thickness_difference - width_difference * modifier, total_key_height - thickness_difference - height_difference * modifier, .001],1.5);
}
}
//dish related stuff
//dish selector
module dish(depth_difference){
if(dish_type == 0){ // cylindrical dish
cylindrical_dish(depth_difference);
}
else if (dish_type == 1) { // spherical dish
spherical_dish(depth_difference);
}
else if (dish_type == 2){ // SIDEWAYS cylindrical dish - used for spacebar
sideways_cylindrical_dish(depth_difference);
}
else if (dish_type == 3){
// no dish
}
}
module cylindrical_dish(depth_difference){
/* we do some funky math here
* basically you want to have the dish "dig in" to the keycap x millimeters
* in order to do that you have to solve a small (2d) system of equations
* where the chord of the spherical cross section of the dish is
* the width of the keycap.
*/
// the distance you have to move the dish up so it digs in dish_depth millimeters
chord_length = (pow(top_total_key_width, 2) - 4 * pow(dish_depth, 2)) / (8 * dish_depth);
//the radius of the dish
rad = (pow(top_total_key_width, 2) + 4 * pow(dish_depth, 2)) / (8 * dish_depth);
if (inverted_dish == 1){
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([90-top_tilt,0,0])
translate([0,-chord_length,0])
cylinder(h=100,r=rad, $fn=1024, center=true);
}
else{
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([90-top_tilt,0,0])
translate([0,chord_length,0])
cylinder(h=100,r=rad, $fn=1024, center=true);
}
}
module spherical_dish(depth_difference){
//same thing as the cylindrical dish here, but we need the corners to just touch - so we have to find the hypotenuse of the top
chord = pow((pow(top_total_key_width,2) + pow(top_total_key_height, 2)),0.5); //getting diagonal of the top
// the distance you have to move the dish up so it digs in dish_depth millimeters
chord_length = (pow(chord, 2) - 4 * pow(dish_depth, 2)) / (8 * dish_depth);
//the radius of the dish
rad = (pow(chord, 2) + 4 * pow(dish_depth, 2)) / (8 * dish_depth);
if (inverted_dish == 1){
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([-top_tilt,0,0])
translate([0,0,-chord_length])
//NOTE: if your dish is long at all you might need to increase this number
sphere(r=rad, $fn=512);
}
else{
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([-top_tilt,0,0])
translate([0,0,chord_length])
sphere(r=rad, $fn=256);
}
}
module sideways_cylindrical_dish(depth_difference){
chord_length = (pow(top_total_key_height, 2) - 4 * pow(dish_depth, 2)) / (8 * dish_depth);
rad = (pow(top_total_key_height, 2) + 4 * pow(dish_depth, 2)) / (8 * dish_depth);
if (inverted_dish == 1){
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([90,top_tilt,90])
translate([0,-chord_length,0])
cylinder(h=total_key_width + 20,r=rad, $fn=1024, center=true); // +20 just cuz
}
else{
translate([dish_skew_x, top_skew + dish_skew_y, total_depth - depth_difference])
rotate([90,top_tilt,90])
translate([0,chord_length,0])
cylinder(h=total_key_width + 20,r=rad, $fn=1024, center=true);
}
}
//actual full key with space carved out and keystem/stabilizer connectors
module key(){
union(){
difference(){
shape(0, 0);
shape(wall_thickness, keytop_thickness);
}
}
}
// ACTUAL OUTPUT
//difference(){
// key();
// preview cube, for seeing inside the keycap
//cube([100,100,100]);
//}
//minkowski_key();
// Experimental stuff
// key rounded with minkowski sum. still supports wall and keytop thickness.
// use in actual output section. takes a long time to render with dishes.
// required for keycap 11, G20 keycap.
module minkowski_key(){
union(){
difference(){
minkowski(){
shape(minkowski_radius*2, minkowski_radius);
difference(){
sphere(r=minkowski_radius, $fn=24);
translate([0,0,-minkowski_radius])
cube([2*minkowski_radius,2*minkowski_radius,2*minkowski_radius], center=true);
}
}
shape(wall_thickness, keytop_thickness);
}
}
connector(has_brim);
if (stabilizers == 1){
stabilizer_connectors(has_brim);
}
}
// NOT 3D, NOT CENTERED
// corollary is roundedRect
module fakeISOEnter(thickness_difference){
z = 0.001;
radius = 2;
/*TODO I figured it out. 18.16 is the actual keycap width / height,
whereas 19.01 is the unit. ISO enter obeys that just like everything else,
which means that it's height is 18.16 * 2 + (19.01 - 18.16) or, two
keycap heights plus the space between them, also known as 18.16 +
(19.01 * (key_height - 1)). this is followed by the width too. should fix
to make this finally work*/
unit = 18.16; // TODO probably not
// t is all modifications to the polygon array
t = radius + thickness_difference/2;
pointArray = [
[0 + t,0 + t],
[unit*1.25 - t, 0 + t],
[unit*1.25 - t, unit*2 - t],
[unit*-.25 + t, unit*2 - t],
[unit*-.25 + t, unit*1 + t],
[0 + t, unit*1 + t]
];
minkowski(){
circle(r=radius, $fn=24);
polygon(points=pointArray);
}
}
//corollary is shape_hull
module ISOEnterShapeHull(thickness_difference, depth_difference, modifier){
unit = 18.16; // TODO probably not
height = 8 - depth_difference;
length = 1.5 * unit; // TODO not used. need for dish
translate([-0.125 * unit, unit*.5]) linear_extrude(height=height*modifier, scale=[.8, .9]){
translate([-unit*.5, -unit*1.5]) minkowski(){
fakeISOEnter(thickness_difference);
}
}
}
Binary file not shown.