2017-08-15 02:48:01 +00:00
|
|
|
include <libraries/geodesic_sphere.scad>
|
2017-08-13 07:04:53 +00:00
|
|
|
include <util.scad>
|
2017-08-15 02:48:01 +00:00
|
|
|
//geodesic looks much better, but runs very slow for anything above a 2u
|
|
|
|
geodesic=false;
|
2017-08-13 07:04:53 +00:00
|
|
|
|
2017-09-25 04:04:34 +00:00
|
|
|
//dish selector
|
|
|
|
module dish(width, height, depth, inverted, tilt) {
|
|
|
|
if($dish_type == "cylindrical"){
|
|
|
|
cylindrical_dish(width, height, depth, inverted, tilt);
|
|
|
|
}
|
|
|
|
else if ($dish_type == "spherical") {
|
|
|
|
spherical_dish(width, height, depth, inverted, tilt);
|
|
|
|
}
|
|
|
|
else if ($dish_type == "sideways cylindrical"){
|
|
|
|
sideways_cylindrical_dish(width, height, depth, inverted, tilt);
|
|
|
|
}
|
|
|
|
// else no dish, "no dish" is the value
|
|
|
|
}
|
2017-08-13 07:04:53 +00:00
|
|
|
|
|
|
|
module cylindrical_dish(width, height, depth, inverted, tilt){
|
|
|
|
// .5 has problems starting around 3u
|
|
|
|
$fa=.25;
|
2017-08-12 05:10:48 +00:00
|
|
|
/* 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.
|
|
|
|
*/
|
2017-08-13 07:04:53 +00:00
|
|
|
// the distance you have to move the dish so it digs in depth millimeters
|
|
|
|
chord_length = (pow(width, 2) - 4 * pow(depth, 2)) / (8 * depth);
|
2017-08-12 05:10:48 +00:00
|
|
|
//the radius of the dish
|
2017-08-13 07:04:53 +00:00
|
|
|
rad = (pow(width, 2) + 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
direction = inverted ? -1 : 1;
|
2017-08-12 05:10:48 +00:00
|
|
|
|
2017-08-13 07:04:53 +00:00
|
|
|
rotate([90-tilt,0,0]){
|
2017-08-12 05:10:48 +00:00
|
|
|
translate([0,chord_length * direction,0]){
|
2017-08-13 07:04:53 +00:00
|
|
|
cylinder(h=height + 20, r=rad, center=true);
|
2017-08-12 05:10:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-25 04:04:34 +00:00
|
|
|
module sideways_cylindrical_dish(width, height, depth, inverted, tilt){
|
|
|
|
$fa=1;
|
|
|
|
chord_length = (pow(height, 2) - 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
rad = (pow(height, 2) + 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
|
|
|
|
direction = inverted ? -1 : 1;
|
|
|
|
|
|
|
|
rotate([90,tilt,90]){
|
|
|
|
translate([0,chord_length * direction,0]){
|
|
|
|
cylinder(h = width + 20,r=rad, center=true); // +20 for fudge factor
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-13 07:04:53 +00:00
|
|
|
module spherical_dish(width, height, depth, inverted, tilt, txt=""){
|
2017-08-15 02:48:01 +00:00
|
|
|
|
|
|
|
//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(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
|
|
|
|
|
|
|
|
// the distance you have to move the dish up so it digs in depth millimeters
|
|
|
|
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
//the radius of the dish
|
|
|
|
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
direction = inverted ? -1 : 1;
|
|
|
|
|
|
|
|
/*intersection(){*/
|
|
|
|
rotate([-tilt,0,0]){
|
|
|
|
translate([0,0,0 * direction]){
|
|
|
|
if (geodesic){
|
|
|
|
$fa=10;
|
|
|
|
geodesic_sphere(r=rad);
|
|
|
|
} else {
|
|
|
|
$fa=1;
|
|
|
|
// rotate 1 because the bottom of the sphere looks like trash.
|
|
|
|
scale([chord/2/depth, chord/2/depth]) {
|
|
|
|
geodesic_sphere(r=depth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// this line causes openscad to die. maybe re-enable when that doesn't happen instead of differencing the inside() when we add the dish to the shape()
|
|
|
|
/*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/
|
|
|
|
/*}*/
|
|
|
|
}
|
|
|
|
|
2017-08-19 16:06:13 +00:00
|
|
|
//the older, 'more accurate', and MUCH slower spherical dish.
|
2017-09-25 04:04:34 +00:00
|
|
|
// generates the largest sphere possible that still contains the chord we are looking for
|
|
|
|
// much more graduated curvature at an immense cost
|
2017-08-19 16:06:13 +00:00
|
|
|
module old_spherical_dish(width, height, depth, inverted, tilt, txt=""){
|
2017-08-15 02:48:01 +00:00
|
|
|
|
2017-08-12 05:10:48 +00:00
|
|
|
//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
|
2017-08-13 07:04:53 +00:00
|
|
|
chord = pow((pow(width,2) + pow(height, 2)),0.5); //getting diagonal of the top
|
2017-08-12 05:10:48 +00:00
|
|
|
|
2017-08-13 07:04:53 +00:00
|
|
|
// the distance you have to move the dish up so it digs in depth millimeters
|
|
|
|
chord_length = (pow(chord, 2) - 4 * pow(depth, 2)) / (8 * depth);
|
2017-08-12 05:10:48 +00:00
|
|
|
//the radius of the dish
|
2017-08-13 07:04:53 +00:00
|
|
|
rad = (pow(chord, 2) + 4 * pow(depth, 2)) / (8 * depth);
|
|
|
|
direction = inverted ? -1 : 1;
|
2017-08-12 05:10:48 +00:00
|
|
|
|
2017-08-13 07:04:53 +00:00
|
|
|
/*intersection(){*/
|
|
|
|
rotate([-tilt,0,0]){
|
|
|
|
translate([0,0,chord_length * direction]){
|
2017-08-15 02:48:01 +00:00
|
|
|
if (geodesic){
|
|
|
|
$fa=3;
|
|
|
|
geodesic_sphere(r=rad);
|
|
|
|
} else {
|
|
|
|
$fa=1;
|
|
|
|
// rotate 1 because the bottom of the sphere looks like trash.
|
|
|
|
%difference() {
|
|
|
|
sphere(r=rad);
|
|
|
|
translate([0,0,rad]) cube(rad*2, center=true);
|
|
|
|
}
|
|
|
|
}
|
2017-08-13 07:04:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// this line causes openscad to die. maybe re-enable when that doesn't happen instead of differencing the inside() when we add the dish to the shape()
|
|
|
|
/*translate([0,0,0]) roundedRect([width, height, depth], 1.5);*/
|
|
|
|
/*}*/
|
2017-08-12 05:10:48 +00:00
|
|
|
}
|