diff --git a/bottlecaps.scad b/bottlecaps.scad index 1c8b901..30916f9 100644 --- a/bottlecaps.scad +++ b/bottlecaps.scad @@ -110,12 +110,12 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP) bottom_half() { difference() { thread_helix( - base_d=threadbase_d-0.1, + d=threadbase_d-0.1, pitch=thread_pitch, thread_depth=thread_h+0.1, thread_angle=thread_angle, twist=810, - higbee=75, + higbee=thread_h*2, anchor=TOP ); zrot_copies(rots=[90,270]) { @@ -192,7 +192,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+2) thread_helix(base_d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, thread_angle=thread_angle, twist=810, higbee=45, internal=true, anchor=BOTTOM); + up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, thread_angle=thread_angle, twist=810, higbee=thread_depth, internal=true, anchor=BOTTOM); } children(); } @@ -303,12 +303,12 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP) up(h-lip_h) { difference() { thread_helix( - base_d=threadbase_d-0.1, + d=threadbase_d-0.1, pitch=thread_pitch, thread_depth=thread_h+0.1, thread_angle=thread_angle, twist=650, - higbee=75, + higbee=thread_h*2, anchor=TOP ); zrot_copies(rots=[90,270]) { @@ -376,7 +376,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+2) thread_helix(base_d=25.5, pitch=2.7, thread_depth=1.6, thread_angle=15, twist=650, higbee=45, internal=true, anchor=BOTTOM); + up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, thread_angle=15, twist=650, higbee=1.6, internal=true, anchor=BOTTOM); } children(); } diff --git a/paths.scad b/paths.scad index cb1b30a..09c5c15 100644 --- a/paths.scad +++ b/paths.scad @@ -950,14 +950,16 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) { // Module: spiral_sweep() // Description: -// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path +// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path. // of a given radius, height and twist. // Arguments: -// path = 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. // r = Radius of the spiral to extrude along. Default: 50 -// d = Diameter of the spiral to extrude along. // twist = number of degrees of rotation to spiral up along height. +// --- +// d = Diameter of the spiral to extrude along. +// higbee = Length to taper thread ends over. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` @@ -965,50 +967,57 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) { // Example: // poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]]; // spiral_sweep(poly, h=200, r=50, twist=1080, $fn=36); -module spiral_sweep(poly, h, r, twist=360, center, d, anchor, spin=0, orient=UP) { - r = get_radius(r=r, d=d, dflt=50); +module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, anchor, spin=0, orient=UP) { poly = path3d(poly); - pline_count = len(poly); - steps = ceil(segs(r)*(twist/360)); 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)); + steps = ceil(sides*(twist/360)); + higbee1 = first_defined([higbee1, higbee, 0]); + higbee2 = first_defined([higbee2, higbee, 0]); + higang1 = 360 * higbee1 / (2 * r1 * PI); + higang2 = 360 * higbee2 / (2 * r2 * PI); + higsteps1 = ceil(higang1/360*sides); + higsteps2 = ceil(higang2/360*sides); + assert(higang1 < twist/2); + assert(higang2 < twist/2); - poly_points = [ - for ( - p = [0:1:steps] - ) let ( - a = twist * (p/steps), - dx = r*cos(a), - dy = r*sin(a), - dz = h * (p/steps), - mat = affine3d_translate([dx, dy, dz-h/2]) * - affine3d_zrot(a) * - affine3d_xrot(90), + function higsize(a) = lookup(a,[ + [-0.001, 0], + for (x=[0.125:0.125:1]) [ x*higang1, pow(x,1/2)], + for (x=[0.125:0.125:1]) [twist-x*higang2, pow(x,1/2)], + [twist+0.001, 0] + ]); + + us = [ + for (i=[0:higsteps1/10:higsteps1]) i, + for (i=[higsteps1+1:1:steps-higsteps2-1]) i, + for (i=[steps-higsteps2:higsteps2/10:steps]) i, + ]; + zang = atan2(r2-r1,h); + points = [ + for (p = us) let ( + u = p / steps, + a = twist * u, + hsc = higsize(a), + r = lerp(r1,r2,u), + mat = affine3d_zrot(a) * + affine3d_translate([r, 0, h * (u-0.5)]) * + affine3d_xrot(90) * + affine3d_skew_xz(xa=zang) * + affine3d_scale([hsc,lerp(hsc,1,0.25),1]), pts = apply(mat, poly) - ) for (pt = pts) pt + ) pts ]; - poly_faces = concat( - [[for (b = [0:1:pline_count-1]) b]], - [ - for ( - p = [0:1:steps-1], - b = [0:1:pline_count-1], - i = [0:1] - ) let ( - b2 = (b == pline_count-1)? 0 : b+1, - p0 = p * pline_count + b, - p1 = p * pline_count + b2, - p2 = (p+1) * pline_count + b2, - p3 = (p+1) * pline_count + b, - pt = (i==0)? [p0, p2, p1] : [p0, p3, p2] - ) pt - ], - [[for (b = [pline_count-1:-1:0]) b+(steps)*pline_count]] + vnf = vnf_vertex_array( + points, col_wrap=true, caps=true, + style=(abs(higbee1)+abs(higbee2))>0? "quincunx" : "alt" ); - tri_faces = triangulate_faces(poly_points, poly_faces); - attachable(anchor,spin,orient, r=r, l=h) { - polyhedron(points=poly_points, faces=tri_faces, convexity=10); + attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { + vnf_polyhedron(vnf, convexity=2*twist/360); children(); } } diff --git a/threading.scad b/threading.scad index 0a2e3bd..391c446 100644 --- a/threading.scad +++ b/threading.scad @@ -11,19 +11,24 @@ // Module: thread_helix() // Usage: -// thread_helix(base_d, pitch, thread_depth, thread_angle, twist, [profile], [left_handed], [higbee], [internal]); +// thread_helix(d, pitch, thread_depth, , , , , , ); // Description: // Creates a helical thread with optional end tapering. // Arguments: -// base_d = Inside base diameter of threads. -// pitch = Distance between threads. +// d = Inside base diameter of threads. Default: 10 +// pitch = Distance between threads. Default: 2mm/thread // thread_depth = Depth of threads from top to bottom. -// thread_angle = Angle of the thread faces. -// twist = Number of degrees to rotate thread around. -// profile = If a an asymmetrical thread profile is needed, it can be specified here. +// thread_angle = Angle of the thread faces. Default: 15 degrees. +// twist = Number of degrees to rotate thread around. Default: 720 degrees. +// --- +// profile = If an asymmetrical thread profile is needed, it can be specified here. // left_handed = If true, thread has a left-handed winding. -// higbee = Angle to taper thread ends by. // internal = If true, invert threads for internal threading. +// d1 = Bottom inside base diameter of threads. +// d2 = Top inside base diameter of threads. +// higbee = Length to taper thread ends over. Default: 0 +// higbee1 = Length to taper bottom thread end over. +// higbee2 = Length to taper top thread end over. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` @@ -31,42 +36,44 @@ // pitch = 2; // depth = pitch * cos(30) * 5/8; // profile = [ -// [-7/16, -depth/pitch*1.07], -// [-6/16, -depth/pitch], -// [-1/16, 0], -// [ 1/16, 0], -// [ 6/16, -depth/pitch], -// [ 7/16, -depth/pitch*1.07] +// [-6/16, 0 ], +// [-1/16, depth/pitch ], +// [ 1/16, depth/pitch ], +// [ 6/16, 0 ], // ]; // stroke(profile, width=0.02); -module thread_helix(base_d, pitch, thread_depth=undef, thread_angle=15, twist=720, profile=undef, left_handed=false, higbee=60, internal=false, anchor=CENTER, spin=0, orient=UP) -{ +// Example: +// thread_helix(d=10, pitch=2, thread_depth=0.75, thread_angle=15, twist=900, $fn=72); +module thread_helix( + d, pitch=2, thread_depth, thread_angle=15, twist=720, + profile, left_handed=false, internal=false, + d1, d2, higbee, higbee1, higbee2, + anchor=CENTER, spin=0, orient=UP +) { h = pitch*twist/360; - r = base_d/2; - dz = thread_depth/pitch * tan(thread_angle); + r1 = get_radius(d1=d1, d=d, dflt=10); + r2 = get_radius(d1=d2, d=d, dflt=10); + tdp = thread_depth / pitch; + dz = tdp * tan(thread_angle); cap = (1 - 2*dz)/2; profile = !is_undef(profile)? profile : ( internal? [ - [thread_depth/pitch, -cap/2-dz], - [0, -cap/2], - [0, +cap/2], - [thread_depth/pitch, +cap/2+dz], + [-cap/2-dz, tdp], + [-cap/2, 0 ], + [+cap/2, 0 ], + [+cap/2+dz, tdp], ] : [ - [0, +cap/2+dz], - [thread_depth/pitch, +cap/2], - [thread_depth/pitch, -cap/2], - [0, -cap/2-dz], + [+cap/2+dz, 0 ], + [+cap/2, tdp], + [-cap/2, tdp], + [-cap/2-dz, 0 ], ] ); - pline = profile * pitch; + pline = mirror([-1,1], p = profile * pitch); dir = left_handed? -1 : 1; idir = internal? -1 : 1; - attachable(anchor,spin,orient, r=r, l=h) { - difference() { - spiral_sweep(pline, h=h, r=base_d/2, twist=twist*dir, $fn=segs(base_d/2), anchor=CENTER); - down(h/2) right(r) right(internal? thread_depth : 0) zrot(higbee*dir*idir) fwd(dir*pitch/2) cube([3*thread_depth/cos(higbee), pitch, pitch], center=true); - up(h/2) zrot(twist*dir) right(r) right(internal? thread_depth : 0) zrot(-higbee*dir*idir) back(dir*pitch/2) cube([3*thread_depth/cos(higbee), pitch, pitch], center=true); - } + attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { + spiral_sweep(pline, h=h, r1=r1, r2=r2, twist=twist*dir, higbee=higbee, higbee1=higbee1, higbee2=higbee2, anchor=CENTER); children(); } } @@ -133,7 +140,7 @@ module trapezoidal_threaded_rod( left_handed=false, bevel=false, starts=1, - profile=undef, + profile, internal=false, center, anchor, spin=0, orient=UP ) { diff --git a/version.scad b/version.scad index 4d83c98..26c4036 100644 --- a/version.scad +++ b/version.scad @@ -6,7 +6,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,551]; +BOSL_VERSION = [2,0,552]; // Section: BOSL Library Version Functions