2017-11-13 05:01:17 +11:00
$fs = . 1 ;
unit = 19.05 ;
module key_shape ( width , height , width_difference , height_difference , corner_size ) {
if ( $ key_shape_type = = "iso_enter" ) {
2017-11-19 08:44:35 +11:00
ISO_enter ( width , height , width_difference , height_difference , corner_size ) ;
2017-11-13 05:01:17 +11:00
} else if ( $ key_shape_type = = "normal" ) {
roundedSquare ( [ width - width_difference , height - height_difference ] , corner_size ) ;
} else if ( $ key_shape_type = = "circle" ) {
circle ( d = width - width_difference ) ;
}
}
// centered
module roundedRect ( size , radius , center = true ) {
linear_extrude ( height = size [ 2 ] ) {
roundedSquare ( [ size [ 0 ] , size [ 1 ] ] , radius , center = center ) ;
}
}
module roundedSquare ( size , radius , center = true ) {
offset ( r = radius ) {
square ( [ size [ 0 ] - radius * 2 , size [ 1 ] - radius * 2 ] , center = center ) ;
}
}
// corollary is roundedSquare
// NOT 3D
2017-11-19 08:44:35 +11:00
module ISO_enter ( width , height , width_difference , height_difference , corner_size ) {
function unit_length ( length ) = unit * ( length - 1 ) + 18.16 ;
2017-11-13 05:01:17 +11:00
2017-11-19 08:44:35 +11:00
// in order to make the ISO keycap shape generic, we are going to express the
// 'elbow point' in terms of ratios. an ISO enter is just a 1.5u key stuck on
// top of a 1.25u key, but since our key_shape function doesnt understand that
// and wants to pass just width and height, we make these ratios to know where
// to put the elbow joint
width_ratio = unit_length ( 1.25 ) / unit_length ( 1.5 ) ;
height_ratio = unit_length ( 1 ) / unit_length ( 2 ) ;
2017-11-13 05:01:17 +11:00
2017-12-11 07:53:44 +11:00
// height and width difference currently don't do anything - but I think I should keep them. they don't do anything because we currently use scaling in the linear_extrude to express the difference in height and width of the top of the keycap
2017-12-06 12:48:11 +11:00
2017-11-13 05:01:17 +11:00
pointArray = [
2017-12-11 07:53:44 +11:00
[ - width_difference / 2 , - height_difference / 2 ] , // top right
[ - width_difference / 2 , - height + height_difference / 2 ] , // bottom right
[ - width * width_ratio + width_difference / 2 , - height + height_difference / 2 ] , // bottom left
[ - width * width_ratio + width_difference / 2 , - height * height_ratio + height_difference / 2 ] , // inner middle point
[ - width + width_difference / 2 , - height * height_ratio + height_difference / 2 ] , // outer middle point
[ - width + width_difference / 2 , - height_difference / 2 ] // top left
2017-11-13 05:01:17 +11:00
] ;
minkowski ( ) {
2017-11-19 08:44:35 +11:00
circle ( r = corner_size ) ;
2017-11-13 05:01:17 +11:00
// gives us rounded inner corner
2017-11-19 08:44:35 +11:00
offset ( r = - corner_size * 2 ) {
translate ( [ ( width * width_ratio ) / 2 , height / 2 ] ) polygon ( points = pointArray ) ;
2017-11-13 05:01:17 +11:00
}
}
}