sculpted_square.scad
1 // rounded square shape with additional sculpting functions to better approximate 2 3 // When sculpting sides, how much in should the tops come 4 $side_sculpting_factor = 4.5; 5 // When sculpting corners, how much extra radius should be added 6 $corner_sculpting_factor = 1; 7 // When doing more side sculpting corners, how much extra radius should be added 8 $more_side_sculpting_factor = 0.4; 9 10 11 // side sculpting functions 12 // bows the sides out on stuff like SA and DSA keycaps 13 function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor; 14 // makes the rounded corners of the keycap grow larger as they move upwards 15 function corner_sculpting(progress) = pow(progress, 2) * $corner_sculpting_factor; 16 17 module sculpted_square_shape(size, delta, progress) { 18 width = size[0]; 19 height = size[1]; 20 21 width_difference = delta[0]; 22 height_difference = delta[1]; 23 // makes the sides bow 24 extra_side_size = side_sculpting(progress); 25 // makes the rounded corners of the keycap grow larger as they move upwards 26 extra_corner_size = corner_sculpting(progress); 27 28 // computed values for this slice 29 extra_width_this_slice = (width_difference - extra_side_size) * progress; 30 extra_height_this_slice = (height_difference - extra_side_size) * progress; 31 extra_corner_radius_this_slice = ($corner_radius + extra_corner_size); 32 33 square_size = [ 34 width - extra_width_this_slice, 35 height - extra_height_this_slice 36 ]; 37 38 offset(r = extra_corner_radius_this_slice, $fa=360/$shape_facets) { 39 offset(r = -extra_corner_radius_this_slice) { 40 side_rounded_square(square_size, r = $more_side_sculpting_factor * progress); 41 } 42 } 43 } 44 45 function new_side_rounded_square(size, r, cornerRadius=0) = 46 let( 47 width = (size.x - r)/2, 48 height = (size.y - r)/2, 49 50 // fudge numbers! the radius conflict resolution in polyround smooths out 51 // the entire shape based on the ratios between conflicting radii. bumping 52 // these up makes the whole shape more fluid 53 widthRadius = r ? width*8 : 0, 54 heightRadius = r ? height*8 : 0, 55 56 bow = r/2, 57 58 // close enough :/ 59 facets = 360 / $shape_facets/2, 60 61 points = [ 62 [-width,-height,cornerRadius], 63 [0,-height-bow,widthRadius], 64 [width,-height,cornerRadius], 65 [width + bow,0,heightRadius], 66 [width,height,cornerRadius], 67 [0,height + bow,widthRadius], 68 [-width,height,cornerRadius], 69 [-width-bow,0,heightRadius] 70 ] 71 ) polyRound(points,facets); 72 73 74 function skin_sculpted_square_shape(size, delta, progress, thickness_difference) = 75 let( 76 width = size[0], 77 height = size[1], 78 79 width_difference = delta[0], 80 height_difference = delta[1], 81 // makes the sides bow 82 extra_side_size = side_sculpting(progress), 83 // makes the rounded corners of the keycap grow larger as they move upwards 84 extra_corner_size = corner_sculpting(progress), 85 86 // computed values for this slice 87 extra_width_this_slice = (width_difference - extra_side_size) * progress, 88 extra_height_this_slice = (height_difference - extra_side_size) * progress, 89 extra_corner_radius_this_slice = ($corner_radius + extra_corner_size), 90 91 square_size = [ 92 width - extra_width_this_slice - thickness_difference, 93 height - extra_height_this_slice - thickness_difference 94 ] 95 ) new_side_rounded_square(square_size, $more_side_sculpting_factor * progress, extra_corner_radius_this_slice); 96 97 98 module side_rounded_square(size, r) { 99 iw = size.x - 2 * r; 100 ih = size.y - 2 * r; 101 resolution = 100; 102 sr = r / resolution * 2; 103 sh = ih / resolution; 104 sw = iw / resolution; 105 union() { 106 if (sr > 0) { 107 translate([-iw/2, 0]) scale([sr, sh]) circle(d = resolution, $fa=360/$shape_facets); 108 translate([iw/2, 0]) scale([sr, sh]) circle(d = resolution, $fa=360/$shape_facets); 109 translate([0, -ih/2]) scale([sw, sr]) circle(d = resolution, $fa=360/$shape_facets); 110 translate([0, ih/2]) scale([sw, sr]) circle(d = resolution, $fa=360/$shape_facets); 111 } 112 square([iw, ih], center=true); 113 } 114 }