spiral_sweep didn't actually do left handed when it was requested

changed higbee options to taper options, with negative for tapers
within specified length and positive for tapers extending the length
This commit is contained in:
Adrian Mariano 2022-12-14 20:03:36 -05:00
parent a15e3e1d43
commit b4a31b82de
3 changed files with 98 additions and 78 deletions

View file

@ -117,7 +117,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
thread_depth=thread_h+0.1, thread_depth=thread_h+0.1,
flank_angle=flank_angle, flank_angle=flank_angle,
turns=810/360, turns=810/360,
higbee=thread_h*2, taper=-thread_h*2,
anchor=TOP anchor=TOP
); );
zrot_copies(rots=[90,270]) { zrot_copies(rots=[90,270]) {
@ -190,7 +190,7 @@ module pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
} }
up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM); up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM);
} }
up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, higbee=thread_depth, internal=true, anchor=BOTTOM); up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, taper=-thread_depth, internal=true, anchor=BOTTOM);
} }
children(); children();
} }
@ -306,7 +306,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
thread_depth=thread_h+0.1, thread_depth=thread_h+0.1,
flank_angle=flank_angle, flank_angle=flank_angle,
turns=650/360, turns=650/360,
higbee=thread_h*2, taper=-thread_h*2,
anchor=TOP anchor=TOP
); );
zrot_copies(rots=[90,270]) { zrot_copies(rots=[90,270]) {
@ -371,7 +371,7 @@ module pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
} }
up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM); up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM);
} }
up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, higbee=1.6, internal=true, anchor=BOTTOM); up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, taper=-1.6, internal=true, anchor=BOTTOM);
} }
children(); children();
} }
@ -475,7 +475,7 @@ module generic_bottle_neck(
thread_depth = thread_h + 0.1 * diamMagMult, thread_depth = thread_h + 0.1 * diamMagMult,
flank_angle = flank_angle, flank_angle = flank_angle,
turns = (height - pitch - lip_roundover_r) * .6167 / pitch, turns = (height - pitch - lip_roundover_r) * .6167 / pitch,
higbee = thread_h * 2, taper = -thread_h * 2,
anchor = TOP anchor = TOP
); );
zrot_copies(rots = [90, 270]) { zrot_copies(rots = [90, 270]) {
@ -578,7 +578,8 @@ module generic_bottle_cap(
} }
difference(){ difference(){
up(wall + pitch / 2) { up(wall + pitch / 2) {
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle, turns = ((height - pitch) / pitch), higbee = threadDepth, internal = true, anchor = BOTTOM); thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle,
turns = ((height - pitch) / pitch), taper = -threadDepth, internal = true, anchor = BOTTOM);
} }
} }
} }
@ -1100,8 +1101,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
profile = _sp_thread_profile(tpi,a,S,style); profile = _sp_thread_profile(tpi,a,S,style);
depth = a/2; depth = a/2;
higlen = 2*a; taperlen = 2*a;
higang = higlen / ((T-2*depth)*PI) * 360;
beadmax = type==400 ? (T/2-depth)+depth*1.25 beadmax = type==400 ? (T/2-depth)+depth*1.25
: diam <=15 ? (T-.15)/2 : (T-.05)/2; : diam <=15 ? (T-.15)/2 : (T-.05)/2;
@ -1126,7 +1126,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
up((H+extra_bot)/2){ up((H+extra_bot)/2){
difference(){ difference(){
union(){ union(){
thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=(twist+2*higang)/360, higbee=higlen, anchor=TOP); thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP);
cylinder(d=T-depth*2,l=H,anchor=TOP); cylinder(d=T-depth*2,l=H,anchor=TOP);
if (bead) if (bead)
down(bead_shift) down(bead_shift)
@ -1144,7 +1144,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
// Module: sp_cap() // Module: sp_cap()
// Usage: // Usage:
// sp_cap(diam, type, wall, [style=], [top_adj=], [bot_adj=], [$slop]) [ATTACHMENTS]; // sp_cap(diam, type, wall, [style=], [top_adj=], [bot_adj=], [texture=], [$slop]) [ATTACHMENTS];
// Description: // Description:
// Make a SPI (Society of Plastics Industry) threaded bottle neck. You must // Make a SPI (Society of Plastics Industry) threaded bottle neck. You must
// supply the nominal outer diameter of the threads and the thread type, one of // supply the nominal outer diameter of the threads and the thread type, one of
@ -1175,6 +1175,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
// style = Either "L" or "M" to specify the thread style. Default: "L" // style = Either "L" or "M" to specify the thread style. Default: "L"
// top_adj = Amount to reduce top space in the cap, which means it doesn't screw down as far. Default: 0 // top_adj = Amount to reduce top space in the cap, which means it doesn't screw down as far. Default: 0
// bot_adj = Amount to reduce extension of cap at the bottom, which also means it doesn't screw down as far. Default: 0 // bot_adj = Amount to reduce extension of cap at the bottom, which also means it doesn't screw down as far. Default: 0
// texture = texture for outside of cap, one of "knurled", "ribbed" or "none. Default: "none"
// $slop = Increase inner diameter by `2 * $slop`. // $slop = Increase inner diameter by `2 * $slop`.
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
@ -1183,7 +1184,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
// sp_cap(48,400,2); // sp_cap(48,400,2);
// sp_cap(22,410,2); // sp_cap(22,410,2);
// sp_cap(28,415,1.5,style="M"); // sp_cap(28,415,1.5,style="M");
module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, anchor, spin, orient) module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anchor, spin, orient)
{ {
table = struct_val(_sp_specs,type); table = struct_val(_sp_specs,type);
dum1=assert(is_def(table),"Unknown SP closure type. Type must be one of 400, 410, or 415"); dum1=assert(is_def(table),"Unknown SP closure type. Type must be one of 400, 410, or 415");
@ -1206,20 +1207,24 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, anchor, spin, orien
profile = fwd(-bounds[0].y,yflip(oprofile)); profile = fwd(-bounds[0].y,yflip(oprofile));
depth = a/2; depth = a/2;
higlen = 2*a; taperlen = 2*a;
higang = higlen / ((T-2*depth)*PI) * 360; assert(in_list(texture, ["none","knurled","ribbed"]));
echo(a=a,depth=depth,halfdepth=depth/2, tpi*pointlist_bounds(profile));
space=2*depth/10+2*get_slop(); space=2*depth/10+2*get_slop();
attachable(anchor,spin,orient,r= (T+space)/2+wall, l=H-bot_adj+wall){ attachable(anchor,spin,orient,r= (T+space)/2+wall, l=H-bot_adj+wall){
xrot(180) xrot(180)
up((H-bot_adj)/2-wall/2){ up((H-bot_adj)/2-wall/2){
difference(){ difference(){
up(wall)cyl(d=T+space+2*wall,l=H+wall-bot_adj,anchor=TOP,chamfer2=.8); up(wall){
if (texture=="knurled")
cyl(d=T+space+2*wall,l=H+wall-bot_adj,anchor=TOP,chamfer2=.8*0,texture="diamonds", tex_size=[3,3], tex_style="concave");
else if (texture == "ribbed")
cyl(d=T+space+2*wall,l=H+wall-bot_adj,anchor=TOP,chamfer2=.8*0,texture="trunc_ribs", tex_size=[3,3], tex_style="min_edge");
else
cyl(d=T+space+2*wall,l=H+wall-bot_adj,anchor=TOP,chamfer2=.8);
}
cyl(d=T+space, l=H-bot_adj+1, anchor=TOP); cyl(d=T+space, l=H-bot_adj+1, anchor=TOP);
} }
thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=(twist+2*higang)/360, higbee=higlen, anchor=TOP, internal=true); thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP, internal=true);
} }
children(); children();
} }

101
skin.scad
View file

@ -991,8 +991,8 @@ module rotate_sweep(
// Function&Module: spiral_sweep() // Function&Module: spiral_sweep()
// Usage: As Module // Usage: As Module
// spiral_sweep(poly, h, r|d=, turns, [higbee=], [center=], [higbee1=], [higbee2=], [internal=], ...)[ATTACHMENTS]; // spiral_sweep(poly, h, r|d=, turns, [taper=], [center=], [taper1=], [taper2=], [internal=], ...)[ATTACHMENTS];
// spiral_sweep(poly, h, r1=|d1=, r2=|d2=, turns, [higbee=], [center=], [higbee1=], [higbee2=], [internal=], ...)[ATTACHMENTS]; // spiral_sweep(poly, h, r1=|d1=, r2=|d2=, turns, [taper=], [center=], [taper1=], [taper2=], [internal=], ...)[ATTACHMENTS];
// Usage: As Function // Usage: As Function
// vnf = spiral_sweep(poly, h, r|d=, turns, ...); // vnf = spiral_sweep(poly, h, r|d=, turns, ...);
// vnf = spiral_sweep(poly, h, r1=|d1=, r1=|d2=, turns, ...); // vnf = spiral_sweep(poly, h, r1=|d1=, r1=|d2=, turns, ...);
@ -1002,19 +1002,22 @@ module rotate_sweep(
// of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius. // of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius.
// If turns is positive the path will be right-handed; if turns is negative the path will be left-handed. // If turns is positive the path will be right-handed; if turns is negative the path will be left-handed.
// . // .
// Higbee specifies tapering applied to the ends of the extrusion and is given as the linear distance // The taper options specify tapering at of the ends of the extrusion, and are given as the linear distance
// over which to taper. // over which to taper. If taper is positive the extrusion lengthened by the specified distance; if taper
// is negative, the taper is included in the extrusion length specified by `turns`.
// Arguments: // Arguments:
// poly = Array of points of a polygon path, to be extruded. // poly = Array of points of a polygon path, to be extruded.
// h = height of the spiral to extrude along. // h = height of the spiral to extrude along.
// r = Radius of the spiral to extrude along. Default: 50 // r = Radius of the spiral to extrude along.
// turns = number of revolutions to spiral up along the height. // turns = number of revolutions to spiral up along the height.
// --- // ---
// d = Diameter of the spiral to extrude along. // d = Diameter of the spiral to extrude along.
// higbee = Length to taper thread ends over. // d1|r1 = Bottom inside diameter or radius of spiral to extrude along.
// higbee1 = Taper length at start // d2|r2 = Top inside diameter or radius of spiral to extrude along.
// higbee2 = Taper length at end // taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0
// internal = direction to taper the threads with higbee. If true threads taper outward; if false they taper inward. Default: false // taper1 = Length of taper for bottom thread end
// taper2 = Length of taper for top thread end
// internal = if true make internal threads. The only effect this has is to change how the extrusion tapers if tapering is selected. When true, the extrusion tapers towards the outside; when false, it tapers towards the inside. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -1026,66 +1029,75 @@ module rotate_sweep(
function _taperfunc(x) = function _taperfunc(x) =
let(higofs = pow(0.05,2)) // Smallest hig scale is the square root of this value let(higofs = pow(0.05,2)) // Smallest hig scale is the square root of this value
sqrt((1-higofs)*x+higofs); sqrt((1-higofs)*x+higofs);
function _taperfunc(x) = function _taperfunc_ellipse(x) =
sqrt(1-(1-x)^2); sqrt(1-(1-x)^2);
function _ss_polygon_r(N,theta) = function _ss_polygon_r(N,theta) =
let( alpha = 360/N ) let( alpha = 360/N )
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2)); cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
function spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor=CENTER, spin=0, orient=UP) = function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) =
assert(is_num(turns) && turns != 0) assert(is_num(turns) && turns != 0)
let( let(
twist = 360*turns, tapersample = 10, // Oversample factor for higbee tapering
higsample = 10, // Oversample factor for higbee tapering dir = sign(turns),
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50),
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50),
bounds = pointlist_bounds(poly), bounds = pointlist_bounds(poly),
yctr = (bounds[0].y+bounds[1].y)/2, yctr = (bounds[0].y+bounds[1].y)/2,
xmin = bounds[0].x, xmin = bounds[0].x,
xmax = bounds[1].x, xmax = bounds[1].x,
poly = path3d(clockwise_polygon(poly)), poly = path3d(clockwise_polygon(poly)),
anchor = get_anchor(anchor,center,BOT,BOT), anchor = get_anchor(anchor,center,BOT,BOT),
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50),
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50),
sides = segs(max(r1,r2)), sides = segs(max(r1,r2)),
dir = sign(twist), ang_step = 360/sides,
ang_step = 360/sides*dir, turns = abs(turns),
orig_anglist = [for(ang = [0:ang_step:twist-EPSILON]) ang, taper1 = first_defined([taper1, taper, 0]),
twist], taper2 = first_defined([taper2, taper, 0]),
higbee1 = first_defined([higbee1, higbee, 0]), taperang1 = 360 * abs(taper1) / (2 * r1 * PI),
higbee2 = first_defined([higbee2, higbee, 0]), taperang2 = 360 * abs(taper2) / (2 * r2 * PI),
higang1 = 360 * higbee1 / (2 * r1 * PI), minang = taper1<=0 ? 0 : -taperang1,
higang2 = 360 * higbee2 / (2 * r2 * PI) tapercut1 = taper1<=0 ? taperang1 : 0,
maxang = taper2<=0 ? 360*turns : 360*turns+taperang2,
tapercut2 = taper2<=0 ? 360*turns-taperang2 : 360*turns
) )
assert(higbee1>=0 && higbee2>=0) assert( tapercut1<tapercut2 && tapercut1<maxang, "Tapers are too long to fit")
assert(higang1 < dir*twist/2,"Higbee1 is more than half the threads") assert( all_positive([r1,r2]), "Diameter/radius must be positive")
assert(higang2 < dir*twist/2,"Higbee2 is more than half the threads")
let( let(
// This complicated sampling scheme is designed to ensure that there is always a facet boundary // This complicated sampling scheme is designed to ensure that faceting always starts at angle zero
// at the $fn specified location, regardless of what kind of subsampling occurs for tapers." // for alignment with cylinders, and there is always a facet boundary at the $fn specified locations,
// regardless of what kind of subsampling occurs for tapers.
orig_anglist = [
if (minang<0) minang,
each reverse([for(ang = [-ang_step:-ang_step:minang+EPSILON]) ang]),
for(ang = [0:ang_step:maxang-EPSILON]) ang,
maxang
],
anglist = [ anglist = [
for(a=orig_anglist) if (a*dir<higang1-EPSILON) a, for(a=orig_anglist) if (a<tapercut1-EPSILON) a,
dir*higang1, tapercut1,
for(a=orig_anglist) if (a*dir>higang1+EPSILON && (twist-a)*dir>higang2+EPSILON) a, for(a=orig_anglist) if (a>tapercut1+EPSILON && a<tapercut2-EPSILON) a,
twist-dir*higang2, tapercut2,
for(a=orig_anglist) if ((twist-a)*dir<higang2-EPSILON) a for(a=orig_anglist) if (a>tapercut2+EPSILON) a
], ],
interp_ang = [ interp_ang = [
for(i=idx(anglist,e=-2)) for(i=idx(anglist,e=-2))
each lerpn(anglist[i],anglist[i+1], each lerpn(anglist[i],anglist[i+1],
(higang1>0 && dir*anglist[i+1]<=higang1) || (higang2>0 && dir*(twist-anglist[i])<=higang2) (taper1!=0 && anglist[i+1]<=tapercut1) || (taper2!=0 && anglist[i]>=tapercut2)
? ceil((anglist[i+1]-anglist[i])/ang_step*higsample) ? ceil((anglist[i+1]-anglist[i])/ang_step*tapersample)
: 1, : 1,
endpoint=false), endpoint=false),
last(anglist) last(anglist)
], ],
e=echo(lenlist=len(interp_ang)),
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)), skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)),
points = [ points = [
for (a = interp_ang) let ( for (a = interp_ang) let (
hsc = dir*a<higang1 ? _taperfunc(dir*a/higang1) hsc = a<tapercut1 ? _taperfunc((a-minang)/taperang1)
: dir*(twist-a)<higang2 ? _taperfunc(dir*(twist-a)/higang2) : a>tapercut2 ? _taperfunc((maxang-a)/taperang2)
: 1, : 1,
u = a/twist, u = a/(360*turns),
r = lerp(r1,r2,u), r = lerp(r1,r2,u),
mat = affine3d_zrot(a) mat = affine3d_zrot(dir*a)
* affine3d_translate([_ss_polygon_r(sides,a)*r, 0, h * (u-0.5)]) * affine3d_translate([_ss_polygon_r(sides,dir*a)*r, 0, dir*h * (u-0.5)])
* affine3d_xrot(90) * affine3d_xrot(90)
* skewmat * skewmat
* scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]), * scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
@ -1102,12 +1114,15 @@ function spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, hi
module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor=CENTER, spin=0, orient=UP) { module spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) {
vnf = spiral_sweep(poly, h, r, turns, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal); vnf = spiral_sweep(poly, h, r, turns, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal);
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50); r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50);
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50); r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50);
taper1 = first_defined([taper1,taper,0]);
taper2 = first_defined([taper2,taper,0]);
extra = PI/2*(max(0,taper1/r1)+max(0,taper2/r2));
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
vnf_polyhedron(vnf, convexity=ceil(abs(2*turns))); vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra)));
children(); children();
} }
} }

View file

@ -1436,9 +1436,8 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
// Module: thread_helix() // Module: thread_helix()
// Usage: // Usage:
// thread_helix(d, pitch, [thread_depth], [flank_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]); // thread_helix(d, pitch, [thread_depth], [flank_angle], [turns], [profile=], [left_handed=], [higbee=], [internal=]);
// Description: // Description:
// Creates a right-handed helical thread with optional end tapering. Unlike // Creates a right-handed helical thread with optional end tapering. Unlike
// {{generic_threaded_rod()}, this module just generates the thread, and you specify the total // {{generic_threaded_rod()}, this module just generates the thread, and you specify the total
// angle of threading that you want, which makes it easy to put complete threads onto a longer // angle of threading that you want, which makes it easy to put complete threads onto a longer
@ -1462,24 +1461,25 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
// unlike the threaded_rod modules, thread_helix does not adjust the diameter for faceting, nor does it // unlike the threaded_rod modules, thread_helix does not adjust the diameter for faceting, nor does it
// subtract any $slop for clearance. // subtract any $slop for clearance.
// . // .
// The taper options specify Higbee specifies tapering applied to the ends of the threads and is given as the linear distance // The taper options specify tapering at of the threads at each end, and is given as the linear distance
// over which to taper. Tapering works on both internal and external threads. // over which to taper. If taper is positive the threads are lengthened by the specified distance; if taper
// is negative, the taper is included in the thread length specified by `turns`. Tapering works on both internal and external threads.
// Arguments: // Arguments:
// d = Inside base diameter of threads. Default: 10 // d = Inside base diameter of threads. Default: 10
// pitch = Distance between threads. Default: 2mm/thread // pitch = Distance between threads. Default: 2
// thread_depth = Depth of threads from top to bottom. // thread_depth = Depth of threads from top to bottom.
// flank_angle = Angle of thread faces to plane perpendicular to screw. Default: 15 degrees. // flank_angle = Angle of thread faces to plane perpendicular to screw. Default: 15 degrees.
// turns = Number of revolutions to rotate thread around. Default: 2. // turns = Number of revolutions to rotate thread around.
// --- // ---
// profile = If an asymmetrical thread profile is needed, it can be specified here. // profile = If an asymmetrical thread profile is needed, it can be specified here.
// starts = The number of thread starts. Default: 1 // starts = The number of thread starts. Default: 1
// left_handed = If true, thread has a left-handed winding. // left_handed = If true, thread has a left-handed winding.
// internal = If true, apply tapers for internal threading, and invert the default profile. Default: false // internal = if true make internal threads. The only effect this has is to change how the threads taper if tapering is selected. When true, threads taper towards the outside; when false, they taper towards the inside. Default: false
// d1 = Bottom inside base diameter of threads. // d1 = Bottom inside base diameter of threads.
// d2 = Top inside base diameter of threads. // d2 = Top inside base diameter of threads.
// higbee = Length to taper thread ends over. Default: 0 // taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0
// higbee1 = Length to taper bottom thread end over. // taper1 = Length of taper for bottom thread end
// higbee2 = Length to taper top thread end over. // taper2 = Length of taper for top thread end
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -1519,19 +1519,19 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
// } // }
// Examples: // Examples:
// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, $fn=72); // thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, $fn=72);
// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, higbee=1, $fn=72); // thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, taper=1, $fn=72);
// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2, higbee=2, internal=true, $fn=72); // thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2, taper=2, internal=true, $fn=72);
// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=1, left_handed=true, higbee=1, $fn=36); // thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=1, left_handed=true, taper=1, $fn=36);
function thread_helix( function thread_helix(
d, pitch, thread_depth, flank_angle, turns=2, d, pitch, thread_depth, flank_angle, turns,
profile, starts=1, left_handed=false, internal=false, profile, starts=1, left_handed=false, internal=false,
d1, d2, higbee, higbee1, higbee2, d1, d2, taper, taper1, taper2,
anchor, spin, orient anchor, spin, orient
) = no_function("thread_helix"); ) = no_function("thread_helix");
module thread_helix( module thread_helix(
d, pitch, thread_depth, flank_angle, turns=2, d, pitch, thread_depth, flank_angle, turns=2,
profile, starts=1, left_handed=false, internal=false, profile, starts=1, left_handed=false, internal=false,
d1, d2, higbee, higbee1, higbee2, d1, d2, taper, taper1, taper2,
anchor, spin, orient anchor, spin, orient
) { ) {
dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile"); dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile");
@ -1562,7 +1562,7 @@ module thread_helix(
dir = left_handed? -1 : 1; dir = left_handed? -1 : 1;
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
zrot_copies(n=starts) { zrot_copies(n=starts) {
spiral_sweep(pline, h=h, r1=r1, r2=r2, turns=turns*dir, higbee=higbee, higbee1=higbee1, higbee2=higbee2, internal=internal, anchor=CENTER); spiral_sweep(pline, h=h, r1=r1, r2=r2, turns=turns*dir, taper=taper, taper1=taper1, taper2=taper2, internal=internal, anchor=CENTER);
} }
children(); children();
} }