diff --git a/readme.md b/readme.md index a272296..294b087 100644 --- a/readme.md +++ b/readme.md @@ -6116,6 +6116,16 @@ it gets the linear dimensions right. See Top diff --git a/tests/png/polyholes.png b/tests/png/polyholes.png index cc77367..6404177 100644 Binary files a/tests/png/polyholes.png and b/tests/png/polyholes.png differ diff --git a/tests/polyholes.scad b/tests/polyholes.scad index 19f66ac..8cf7528 100644 --- a/tests/polyholes.scad +++ b/tests/polyholes.scad @@ -21,30 +21,60 @@ include <../utils/core/core.scad> use <../vitamins/rod.scad> include <../vitamins/sheets.scad> -module polyholes() { - module positions() - for(i = [1 : 10]) { - translate([(i * i + i) / 2 + 3 * i , 8]) - let($r = i / 2) +module positions() + for(i = [1 : 10]) { + translate([(i * i + i) / 2 + 3 * i , 8]) + let($r = i / 2) + children(); + + let(d = i + 0.5) + translate([(d * d + d) / 2 + 3 * d, 19]) + let($r = d / 2) children(); + } - let(d = i + 0.5) - translate([(d * d + d) / 2 + 3 * d, 19]) - let($r = d / 2) - children(); - } +module polyhole_stl() { + stl("polyhole"); - stl_colour(pp1_colour) linear_extrude(3, center = true) + linear_extrude(3, center = true) difference() { square([100, 27]); positions() poly_circle(r = $r); } +} - positions() +module alt_polyhole_stl() { + holes = [2.5, 2, 1.5]; + n = len(holes); + size = [n * 10, 10, 10]; + difference() { + translate([-size.x / n / 2, $preview ? 0 : -size.y / 2]) + cube($preview ? [size.x, size.y / 2, size.z] : size); + + for(i = [0 : n - 1]) + translate([i * 10, 0]) + if(i % 2) + translate_z(size.z) + poly_cylinder(r = holes[i] / 2, h = 2 * size.z, center = true, twist = i + 1); + else + poly_cylinder(r = holes[i] / 2, h = size.z, center = false, twist = i + 1); + } +} + +module polyholes() { + stl_colour(pp1_colour) + polyhole_stl(); + + positions() rod(d = 2 * $r, l = 8 * $r + 5); // + // Alternating polyholes + // + translate([30, -40]) + alt_polyhole_stl(); + // // Poly rings // ir = 3 / 2; @@ -74,4 +104,11 @@ module polyholes() { } } -polyholes(); +if($preview) + polyholes(); +else { + polyhole_stl(); + + translate([50, -20]) + alt_polyhole_stl(); +} diff --git a/utils/core/polyholes.scad b/utils/core/polyholes.scad index 82ec71f..99a48ac 100644 --- a/utils/core/polyholes.scad +++ b/utils/core/polyholes.scad @@ -22,6 +22,16 @@ //! it gets the linear dimensions right. See //! //! The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is useful for making printed washers and pillars. +//! +//! `poly_cylinder()` has a `twist` parameter which can be set to make the polygon rotate each layer. +//! This can be used to mitigate the number of sides being small and make small holes stronger and more round, but is quite slow due to the +//! large increase in the number of facets. +//! When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat. +//! A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when +//! veiwed end on. +//! +//! When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without +//! leaving a scar on either surface. // function sides(r) = max(round(4 * r), 3); //! Optimium number of sides for specified radius function corrected_radius(r, n = 0) = r / cos(180 / (n ? n : sides(r))); //! Adjusted radius to make flats lie on the circle @@ -32,9 +42,26 @@ module poly_circle(r, sides = 0) { //! Make a circle adjusted to print the corre circle(r = corrected_radius(r,n), $fn = n); } -module poly_cylinder(r, h, center = false, sides = 0, chamfer = false) {//! Make a cylinder adjusted to print the correct size - extrude_if(h, center) - poly_circle(r, sides); +module poly_cylinder(r, h, center = false, sides = 0, chamfer = false, twist = 0) {//! Make a cylinder adjusted to print the correct size + if(twist) { + slices = ceil(h / layer_height); + twist = min(twist, slices - 1); + sides = sides ? sides : sides(r); + rot = 360 / sides / (twist + 1) * (1 + 1 / slices); + if(center) + for(side = [0, 1]) + mirror([0, 0, side]) + poly_cylinder(r = r, h = h / 2, sides = sides, twist = twist); + else + render(convexity = 5) + for(i = [0 : slices - 1]) + translate_z(i * layer_height - eps) + rotate(rot * i) + poly_cylinder(r = r, h = layer_height + 2 * eps, sides = sides); + } + else + extrude_if(h, center) + poly_circle(r, sides); if(h && chamfer) poly_cylinder(r + layer_height, center ? layer_height * 2 : layer_height, center, sides = sides ? sides : sides(r));