diff --git a/readme.md b/readme.md index 245f382..de48258 100644 --- a/readme.md +++ b/readme.md @@ -5546,6 +5546,8 @@ specify a chamfer angle. Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for example to make a printed pot with a screw top lid. +A left hand thread can be made by using mirror([0,1]). + Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix. diff --git a/tests/png/thread.png b/tests/png/thread.png index 8e2a221..cd5010d 100644 Binary files a/tests/png/thread.png and b/tests/png/thread.png differ diff --git a/tests/thread.scad b/tests/thread.scad index 6cceecc..c00cd87 100644 --- a/tests/thread.scad +++ b/tests/thread.scad @@ -26,27 +26,27 @@ profile = thread_profile(pitch / 2, pitch * 0.366, 30); module threads() for(female = [false, true]) translate([0, female ? -20 : 0]) { - length = female ? 8 : 40; - dia = female ? 8 : 8 - pitch; - colour = female ? brass : silver; + length = female ? 8 : 40; + dia = female ? 8 : 8 - pitch; + colour = female ? brass : silver; - thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour); + thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour); - color(colour) - translate([20, 0]) - thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female); + color(colour) + translate([20, 0]) + thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female); - translate([40, 0]) - thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour); + translate([40, 0]) + thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour); - color(colour) - translate([60, 0]) - thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female); + color(colour) + translate([60, 0]) + thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female); - color(colour) - translate([80, 0]) - thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female); -} + color(colour) + translate([80, 0]) + thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female); + } let($show_threads = true) threads(); diff --git a/utils/thread.scad b/utils/thread.scad index fc14fc7..4b1c360 100644 --- a/utils/thread.scad +++ b/utils/thread.scad @@ -26,6 +26,8 @@ //! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for //! example to make a printed pot with a screw top lid. //! +//! A left hand thread can be made by using mirror([0,1]). +//! //! Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of //! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix. //! @@ -61,10 +63,12 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st // Extract some properties from the profile, perhaps they should be stored in it. // h = max([for(p = sprofile) p.y]); - maxx = max([for(p = sprofile) p.x]); - minx = min([for(p = sprofile) p.x]); - crest_xmax = max([for(p = sprofile) if(p.x != maxx) p.x]); - crest_xmin = min([for(p = sprofile) if(p.x != minx) p.x]); + xs = [for(p = sprofile) p.x]; + maxx = max(xs); + minx = min(xs); + crest_xs = [for(p = sprofile) if(p.y == h) p.x]; + crest_xmax = max(crest_xs); + crest_xmin = min(crest_xs); // // If the ends don't taper we need an extra half turn past the ends to be cropped horizontally. // @@ -129,11 +133,13 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st render() intersection() { polyhedron(points, ends_faces); - len = length - 2 * eps; + shorten = !is_undef(colour); + len = shorten ? length - 2 * eps : length; + offset = shorten ? eps : 0; rotate_extrude() if(female) { difference() { - translate([0, eps]) + translate([0, offset]) square([r + h + overlap, len]); if(top_chamfer_h) @@ -146,7 +152,7 @@ module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, st else difference() { hull() { - translate([0, eps]) + translate([0, offset]) square([r, len]); translate([0, bot_chamfer_h])