promote sculpted, rounded squares into their own shape

This commit is contained in:
Robert Sheldon 2018-06-24 17:13:51 -04:00
parent aa3fed7755
commit 50ad7c73ed
8 changed files with 124 additions and 114 deletions

View File

@ -38,4 +38,19 @@ for (p = [0:len(key_profiles)-1]) {
} }
/* translate_u(0, 0) one_row_profile("oem"); */ /* translate_u(0, 0) one_row_profile("oem"); */
legend("C", [-1,-1], 3) cherry() key(true); /* dsa_row(3) u(1) uh(1) cherry() key(); */
translate_u(0) sa_row(3) cherry() {
key();
}
translate_u(1) sa_row(2) cherry() {
key();
}
translate_u(2) sa_row(1) cherry() {
key();
}
/* sculpted_square_shape([19,19], [0,0], 0.3);
translate([26,0,0]) rounded_square_shape([19,19], [0,0], 0.3); */

View File

@ -1,5 +1,6 @@
module dsa_row(n=3) { module dsa_row(n=3) {
depth_raisers = [0, 3.5, 1, 0, 1, 3]; $key_shape_type = "sculpted_square";
depth_raisers = [0, 3.5, 1, 0, 1, 3];
$bottom_key_width = 18.24; // 18.4; $bottom_key_width = 18.24; // 18.4;
$bottom_key_height = 18.24; // 18.4; $bottom_key_height = 18.24; // 18.4;
$width_difference = 6; // 5.7; $width_difference = 6; // 5.7;
@ -8,11 +9,10 @@ module dsa_row(n=3) {
$top_tilt = n == 5 ? -21 : (n-3) * 7; $top_tilt = n == 5 ? -21 : (n-3) * 7;
$top_skew = 0; $top_skew = 0;
$dish_type = "spherical"; $dish_type = "spherical";
$dish_depth = 1.2; $dish_depth = 1;
$dish_skew_x = 0; $dish_skew_x = 0;
$dish_skew_y = 0; $dish_skew_y = 0;
$height_slices = 10; $height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski // might wanna change this if you don't minkowski
// do you even minkowski bro // do you even minkowski bro
$corner_radius = 0.25; $corner_radius = 0.25;

View File

@ -1,4 +1,5 @@
module sa_row(n=1) { module sa_row(n=1) {
$key_shape_type = "sculpted_square";
$bottom_key_width = 18.4; $bottom_key_width = 18.4;
$bottom_key_height = 18.4; $bottom_key_height = 18.4;
$width_difference = 5.7; $width_difference = 5.7;
@ -9,7 +10,6 @@ module sa_row(n=1) {
$dish_skew_y = 0; $dish_skew_y = 0;
$top_skew = 0; $top_skew = 0;
$height_slices = 10; $height_slices = 10;
$enable_side_sculpting = true;
// might wanna change this if you don't minkowski // might wanna change this if you don't minkowski
// do you even minkowski bro // do you even minkowski bro
$corner_radius = 0.25; $corner_radius = 0.25;

View File

@ -5,26 +5,26 @@ function combine_se3_exp(w, ABt) = construct_Rt(rodrigues_so3_exp(w, ABt[0], ABt
// [A,B,t] // [A,B,t]
function se3_exp_1(t,w) = concat( function se3_exp_1(t,w) = concat(
so3_exp_1(w*w), so3_exp_1(w*w),
[t + 0.5 * cross(w,t)] [t + 0.5 * cross(w,t)]
); );
function se3_exp_2(t,w) = se3_exp_2_0(t,w,w*w); function se3_exp_2(t,w) = se3_exp_2_0(t,w,w*w);
function se3_exp_2_0(t,w,theta_sq) = function se3_exp_2_0(t,w,theta_sq) =
se3_exp_23( se3_exp_23(
so3_exp_2(theta_sq), so3_exp_2(theta_sq),
C = (1.0 - theta_sq/20) / 6, C = (1.0 - theta_sq/20) / 6,
t=t,w=w); t=t,w=w);
function se3_exp_3(t,w) = se3_exp_3_0(t,w,sqrt(w*w)*180/PI,1/sqrt(w*w)); function se3_exp_3(t,w) = se3_exp_3_0(t,w,sqrt(w*w)*180/PI,1/sqrt(w*w));
function se3_exp_3_0(t,w,theta_deg,inv_theta) = function se3_exp_3_0(t,w,theta_deg,inv_theta) =
se3_exp_23( se3_exp_23(
so3_exp_3_0(theta_deg = theta_deg, inv_theta = inv_theta), so3_exp_3_0(theta_deg = theta_deg, inv_theta = inv_theta),
C = (1 - sin(theta_deg) * inv_theta) * (inv_theta * inv_theta), C = (1 - sin(theta_deg) * inv_theta) * (inv_theta * inv_theta),
t=t,w=w); t=t,w=w);
function se3_exp_23(AB,C,t,w) = function se3_exp_23(AB,C,t,w) =
[AB[0], AB[1], t + AB[1] * cross(w,t) + C * cross(w,cross(w,t)) ]; [AB[0], AB[1], t + AB[1] * cross(w,t) + C * cross(w,cross(w,t)) ];
function se3_exp(mu) = se3_exp_0(t=take3(mu),w=tail3(mu)/180*PI); function se3_exp(mu) = se3_exp_0(t=take3(mu),w=tail3(mu)/180*PI);
@ -32,29 +32,29 @@ function se3_exp(mu) = se3_exp_0(t=take3(mu),w=tail3(mu)/180*PI);
function se3_exp_0(t,w) = function se3_exp_0(t,w) =
combine_se3_exp(w, combine_se3_exp(w,
// Evaluate by Taylor expansion when near 0 // Evaluate by Taylor expansion when near 0
w*w < 1e-8 w*w < 1e-8
? se3_exp_1(t,w) ? se3_exp_1(t,w)
: w*w < 1e-6 : w*w < 1e-6
? se3_exp_2(t,w) ? se3_exp_2(t,w)
: se3_exp_3(t,w) : se3_exp_3(t,w)
); );
function se3_ln(m) = se3_ln_to_deg(se3_ln_rad(m)); function se3_ln(m) = se3_ln_to_deg(se3_ln_rad(m));
function se3_ln_to_deg(v) = concat(take3(v),tail3(v)*180/PI); function se3_ln_to_deg(v) = concat(take3(v),tail3(v)*180/PI);
function se3_ln_rad(m) = se3_ln_0(m, function se3_ln_rad(m) = se3_ln_0(m,
rot = so3_ln_rad(rotation_part(m))); rot = so3_ln_rad(rotation_part(m)));
function se3_ln_0(m,rot) = se3_ln_1(m,rot, function se3_ln_0(m,rot) = se3_ln_1(m,rot,
theta = sqrt(rot*rot)); theta = sqrt(rot*rot));
function se3_ln_1(m,rot,theta) = se3_ln_2(m,rot,theta, function se3_ln_1(m,rot,theta) = se3_ln_2(m,rot,theta,
shtot = theta > 0.00001 ? sin(theta/2*180/PI)/theta : 0.5, shtot = theta > 0.00001 ? sin(theta/2*180/PI)/theta : 0.5,
halfrotator = so3_exp_rad(rot * -.5)); halfrotator = so3_exp_rad(rot * -.5));
function se3_ln_2(m,rot,theta,shtot,halfrotator) = function se3_ln_2(m,rot,theta,shtot,halfrotator) =
concat( (halfrotator * translation_part(m) - concat( (halfrotator * translation_part(m) -
(theta > 0.001 (theta > 0.001
? rot * ((translation_part(m) * rot) * (1-2*shtot) / (rot*rot)) ? rot * ((translation_part(m) * rot) * (1-2*shtot) / (rot*rot))
: rot * ((translation_part(m) * rot)/24) : rot * ((translation_part(m) * rot)/24)
)) / (2 * shtot), rot); )) / (2 * shtot), rot);
__se3_test = [20,-40,60,-80,100,-120]; __se3_test = [20,-40,60,-80,100,-120];
echo(UNITTEST_se3=norm(__se3_test-se3_ln(se3_exp(__se3_test))) < 1e-8); echo(UNITTEST_se3=norm(__se3_test-se3_ln(se3_exp(__se3_test))) < 1e-8);

View File

@ -75,16 +75,6 @@ $dish_overdraw_height = 0;
// how many slices will be made, to approximate curves on corners. Leave at 1 if you are not curving corners // how many slices will be made, to approximate curves on corners. Leave at 1 if you are not curving corners
// if you're doing fancy bowed keycap sides, this controls how many slices you take // if you're doing fancy bowed keycap sides, this controls how many slices you take
$height_slices = 1; $height_slices = 1;
// this enables some fancy and currently hardcoded logic to bow the sides and corners of SA keycaps
$enable_side_sculpting = false;
// this enables even more fancy and hardcoded logic for corner bowing of SA keycaps. (Also needs enable_side_sculpting to be true)
$enable_more_side_sculpting = false;
// When sculpting sides, how much in should the tops come
$side_sculpting_factor = 2.5;
// When sculpting corners, how much extra radius should be added
$corner_sculpting_factor = 1;
// When doing more side sculpting corners, how much extra radius should be added
$more_side_sculpting_factor = 0.4;
//minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20 //minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20
$minkowski_radius = .33; $minkowski_radius = .33;

View File

@ -2,6 +2,7 @@ $fs=.1;
unit = 19.05; unit = 19.05;
include <shapes/ISO_enter.scad> include <shapes/ISO_enter.scad>
include <shapes/sculpted_square.scad>
include <shapes/rounded_square.scad> include <shapes/rounded_square.scad>
include <shapes/square.scad> include <shapes/square.scad>
include <shapes/oblong.scad> include <shapes/oblong.scad>
@ -9,6 +10,8 @@ include <shapes/oblong.scad>
module key_shape(size, delta, progress = 0) { module key_shape(size, delta, progress = 0) {
if ($key_shape_type == "iso_enter") { if ($key_shape_type == "iso_enter") {
ISO_enter_shape(size, delta, progress); ISO_enter_shape(size, delta, progress);
} else if ($key_shape_type == "sculpted_square") {
sculpted_square_shape(size, delta, progress);
} else if ($key_shape_type == "rounded_square") { } else if ($key_shape_type == "rounded_square") {
rounded_square_shape(size, delta, progress); rounded_square_shape(size, delta, progress);
} else if ($key_shape_type == "square") { } else if ($key_shape_type == "square") {

View File

@ -1,79 +1,22 @@
// side sculpting functions
// bows the sides out on stuff like SA and DSA keycaps
function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor;
// makes the rounded corners of the keycap grow larger as they move upwards
function corner_sculpting(progress) = pow(progress, 2) * $corner_sculpting_factor;
module rounded_square_shape(size, delta, progress, center = true) { module rounded_square_shape(size, delta, progress, center = true) {
width = size[0]; width = size[0];
height = size[1]; height = size[1];
width_difference = delta[0]; width_difference = delta[0];
height_difference = delta[1]; height_difference = delta[1];
// makes the sides bow
extra_side_size = $enable_side_sculpting ? side_sculpting(progress) : 0;
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = $enable_side_sculpting ? corner_sculpting(progress) : 0;
// computed values for this slice // computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress; extra_width_this_slice = (width_difference) * progress;
extra_height_this_slice = (height_difference - extra_side_size) * progress; extra_height_this_slice = (height_difference) * progress;
extra_corner_radius_this_slice = ($corner_radius + extra_corner_size); extra_corner_radius_this_slice = ($corner_radius);
square_size = [width - extra_width_this_slice, height - extra_height_this_slice]; offset(r=extra_corner_radius_this_slice){
offset(r = extra_corner_radius_this_slice) offset(r = -extra_corner_radius_this_slice) { square(
if ($enable_more_side_sculpting != false && progress > 0) { [
side_rounded_square(square_size, r = $more_side_sculpting_factor * progress); width - extra_width_this_slice - extra_corner_radius_this_slice * 2,
} else { height - extra_height_this_slice - extra_corner_radius_this_slice * 2
square(square_size, center=center); ],
} center=center
} );
}
// Brings in a square at each corner by r, applied over the length of each side.
module side_rounded_square(size, r) {
if ($enable_more_side_sculpting == "slow") {
side_rounded_square_slow(size, r);
} else {
side_rounded_square_fast(size, r);
}
}
module side_rounded_square_fast(size, r) {
iw = size.x - 2 * r;
ih = size.y - 2 * r;
resolution = 100;
sr = r / resolution * 2;
sh = ih / resolution;
sw = iw / resolution;
union() {
translate([-iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([0, -ih/2]) scale([sw, sr]) circle(d = resolution);
translate([0, ih/2]) scale([sw, sr]) circle(d = resolution);
square([iw, ih], center=true);
}
}
module side_rounded_square_slow(size, r) {
// These two from: https://openscadsnippetpad.blogspot.co.nz/2017/05/circle-defined-by-three-points.html
function len3(v) = sqrt(pow(v.x, 2) + pow(v.y, 2));
function circle_by_three_points(A, B, C) = let (
yD_b = C.y - B.y, xD_b = C.x - B.x, yD_a = B.y - A.y,
xD_a = B.x - A.x, aS = yD_a / xD_a, bS = yD_b / xD_b,
cex = (aS * bS * (A.y - C.y) + bS * (A.x + B.x) - aS * (B.x + C.x)) / (2 * (bS - aS)),
cey = -1 * (cex - (A.x + B.x) / 2) / aS + (A.y + B.y) / 2
)
[cex, cey];
w = size.x - r * 2;
h = size.y - r * 2;
cw = circle_by_three_points([-w / 2, 0], [0, r], [w / 2, 0]);
rw = len3([w / 2, 0] - cw);
ch = circle_by_three_points([0, -h / 2], [r, 0], [0, h / 2]);
rh = len3([0, h / 2] - ch);
intersection() {
translate(cw + [0, h / 2]) circle(r = rw, $fa=1);
translate(cw * -1 + [0, -h / 2]) circle(r = rw, $fa=1);
translate(ch + [w / 2, 0]) circle(r = rh, $fa=1);
translate(ch * -1 + [-w / 2, 0]) circle(r = rh, $fa=1);
} }
} }

View File

@ -0,0 +1,59 @@
// rounded square shape with additional sculpting functions to better approximate
// When sculpting sides, how much in should the tops come
$side_sculpting_factor = 4.5;
// When sculpting corners, how much extra radius should be added
$corner_sculpting_factor = 1;
// When doing more side sculpting corners, how much extra radius should be added
$more_side_sculpting_factor = 0.4;
// side sculpting functions
// bows the sides out on stuff like SA and DSA keycaps
function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor;
// makes the rounded corners of the keycap grow larger as they move upwards
function corner_sculpting(progress) = pow(progress, 2) * $corner_sculpting_factor;
module sculpted_square_shape(size, delta, progress) {
width = size[0];
height = size[1];
width_difference = delta[0];
height_difference = delta[1];
// makes the sides bow
extra_side_size = side_sculpting(progress);
// makes the rounded corners of the keycap grow larger as they move upwards
extra_corner_size = corner_sculpting(progress);
// computed values for this slice
extra_width_this_slice = (width_difference - extra_side_size) * progress;
extra_height_this_slice = (height_difference - extra_side_size) * progress;
extra_corner_radius_this_slice = ($corner_radius + extra_corner_size);
square_size = [
width - extra_width_this_slice,
height - extra_height_this_slice
];
offset(r = extra_corner_radius_this_slice) {
offset(r = -extra_corner_radius_this_slice) {
side_rounded_square(square_size, r = $more_side_sculpting_factor * progress);
}
}
}
module side_rounded_square(size, r) {
iw = size.x - 2 * r;
ih = size.y - 2 * r;
resolution = 100;
sr = r / resolution * 2;
sh = ih / resolution;
sw = iw / resolution;
union() {
translate([-iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([iw/2, 0]) scale([sr, sh]) circle(d = resolution);
translate([0, -ih/2]) scale([sw, sr]) circle(d = resolution);
translate([0, ih/2]) scale([sw, sr]) circle(d = resolution);
square([iw, ih], center=true);
}
}