mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 00:09:41 +00:00
Fixed higbee=0 problem in spiral_sweep, cleaned up thread_helix. Made
spiral sweep force its input to be clockwise to avoid reversed polyhedra. Changed thread_angle in thread_helix to flank_angle, which is the correct term for this angle, and then propagated change in bottlecap.scad.
This commit is contained in:
parent
6e0b966b72
commit
6da612f7e6
3 changed files with 60 additions and 43 deletions
|
@ -53,7 +53,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
tamper_base_h = 14.10;
|
||||
threadbase_d = 24.51;
|
||||
thread_pitch = 3.18;
|
||||
thread_angle = 20;
|
||||
flank_angle = 20;
|
||||
thread_od = 27.43;
|
||||
lip_d = 25.07;
|
||||
lip_h = 1.70;
|
||||
|
@ -113,7 +113,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
d=threadbase_d-0.1,
|
||||
pitch=thread_pitch,
|
||||
thread_depth=thread_h+0.1,
|
||||
thread_angle=thread_angle,
|
||||
flank_angle=flank_angle,
|
||||
twist=810,
|
||||
higbee=thread_h*2,
|
||||
anchor=TOP
|
||||
|
@ -164,7 +164,7 @@ module pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
|
|||
cap_id = 28.58;
|
||||
tamper_ring_h = 14.10;
|
||||
thread_pitch = 3.18;
|
||||
thread_angle = 20;
|
||||
flank_angle = 20;
|
||||
thread_od = cap_id;
|
||||
thread_depth = 1.6;
|
||||
|
||||
|
@ -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(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);
|
||||
up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, twist=810, higbee=thread_depth, internal=true, anchor=BOTTOM);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
tamper_divot_r = 1.08;
|
||||
threadbase_d = 24.20;
|
||||
thread_pitch = 2.70;
|
||||
thread_angle = 15;
|
||||
flank_angle = 15;
|
||||
thread_od = 27.4;
|
||||
lip_d = 25.07;
|
||||
lip_h = 1.70;
|
||||
|
@ -306,7 +306,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
d=threadbase_d-0.1,
|
||||
pitch=thread_pitch,
|
||||
thread_depth=thread_h+0.1,
|
||||
thread_angle=thread_angle,
|
||||
flank_angle=flank_angle,
|
||||
twist=650,
|
||||
higbee=thread_h*2,
|
||||
anchor=TOP
|
||||
|
@ -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(d=25.5, pitch=2.7, thread_depth=1.6, thread_angle=15, twist=650, 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, twist=650, higbee=1.6, internal=true, anchor=BOTTOM);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ module generic_bottle_neck(
|
|||
neck_d = neck_d;
|
||||
supp_d = max(neck_d, support_d);
|
||||
thread_pitch = pitch;
|
||||
thread_angle = 15;
|
||||
flank_angle = 15;
|
||||
|
||||
diamMagMult = neck_d / 26.19;
|
||||
heightMagMult = height / 17.00;
|
||||
|
@ -478,7 +478,7 @@ module generic_bottle_neck(
|
|||
d = threadbase_d - 0.1 * diamMagMult,
|
||||
pitch = thread_pitch,
|
||||
thread_depth = thread_h + 0.1 * diamMagMult,
|
||||
thread_angle = thread_angle,
|
||||
flank_angle = flank_angle,
|
||||
twist = 360 * (height - pitch - lip_roundover_r) * .6167 / pitch,
|
||||
higbee = thread_h * 2,
|
||||
anchor = TOP
|
||||
|
@ -527,7 +527,7 @@ function generic_bottle_neck(
|
|||
// thread_od = Outer diameter of the threads in mm.
|
||||
// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius.
|
||||
// neck_od = Outer diameter of neck in mm.
|
||||
// thread_angle = Angle of taper on threads.
|
||||
// flank_angle = Angle of taper on threads.
|
||||
// pitch = Thread pitch in mm.
|
||||
// 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`
|
||||
|
@ -545,7 +545,7 @@ module generic_bottle_cap(
|
|||
thread_od = 28.58,
|
||||
tolerance = .2,
|
||||
neck_od = 25.5,
|
||||
thread_angle = 15,
|
||||
flank_angle = 15,
|
||||
pitch = 4,
|
||||
anchor = BOTTOM,
|
||||
spin = 0,
|
||||
|
@ -587,7 +587,7 @@ module generic_bottle_cap(
|
|||
}
|
||||
difference(){
|
||||
up(wall + pitch / 2) {
|
||||
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, thread_angle = thread_angle, twist = 360 * ((height - pitch) / pitch), higbee = threadDepth, internal = true, anchor = BOTTOM);
|
||||
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle, twist = 360 * ((height - pitch) / pitch), higbee = threadDepth, internal = true, anchor = BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -598,7 +598,7 @@ module generic_bottle_cap(
|
|||
function generic_bottle_cap(
|
||||
wall, texture, height,
|
||||
thread_od, tolerance,
|
||||
neck_od, thread_angle, pitch,
|
||||
neck_od, flank_angle, pitch,
|
||||
anchor, spin, orient
|
||||
) = no_function("generic_bottle_cap");
|
||||
|
||||
|
@ -689,7 +689,7 @@ module bottle_adapter_neck_to_cap(
|
|||
thread_od = cap_thread_od,
|
||||
tolerance = tolerance,
|
||||
neck_od = cap_neck_od,
|
||||
thread_angle = cap_thread_taper,
|
||||
flank_angle = cap_thread_taper,
|
||||
orient = DOWN,
|
||||
pitch = cap_thread_pitch
|
||||
);
|
||||
|
|
29
paths.scad
29
paths.scad
|
@ -1030,8 +1030,11 @@ 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.
|
||||
// of a given radius, height and twist.
|
||||
// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a right-handed 3D spiral path
|
||||
// of a given radius, height and twist. The origin in the profile traces out the helix of the specified radius.
|
||||
// .
|
||||
// Higbee specifies tapering applied to the ends of the extrusion and is given as the linear distance
|
||||
// over which to taper.
|
||||
// Arguments:
|
||||
// poly = Array of points of a polygon path, to be extruded.
|
||||
// h = height of the spiral to extrude along.
|
||||
|
@ -1055,7 +1058,7 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
|
|||
yctr = (bounds[0].y+bounds[1].y)/2;
|
||||
xmin = bounds[0].x;
|
||||
xmax = bounds[1].x;
|
||||
poly = path3d(poly);
|
||||
poly = path3d(clockwise_polygon(poly));
|
||||
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);
|
||||
|
@ -1063,17 +1066,19 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
|
|||
steps = ceil(sides*(twist/360));
|
||||
higbee1 = first_defined([higbee1, higbee, 0]);
|
||||
higbee2 = first_defined([higbee2, higbee, 0]);
|
||||
assert(higbee1>=0 && higbee2>=0);
|
||||
higang1 = 360 * higbee1 / (2 * r1 * PI);
|
||||
higang2 = 360 * higbee2 / (2 * r2 * PI);
|
||||
higsteps1 = ceil(higang1/360*sides);
|
||||
higsteps2 = ceil(higang2/360*sides);
|
||||
assert(twist>0);
|
||||
assert(higang1 < twist/2);
|
||||
assert(higang2 < twist/2);
|
||||
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]
|
||||
[-0.001, higang1>0?0:1],
|
||||
if (higang1>0) for (x=[0.125:0.125:1]) [ x*higang1, pow(x,1/2)],
|
||||
if (higang2>0) for (x=[0.125:0.125:1]) [twist-x*higang2, pow(x,1/2)],
|
||||
[twist+0.001, higang2>0?0:1]
|
||||
]);
|
||||
|
||||
us = [
|
||||
|
@ -1089,11 +1094,13 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
|
|||
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_skew_xz(xa=zang) *
|
||||
//affine3d_scale([hsc,lerp(hsc,1,0.25),1]),
|
||||
scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
|
||||
pts = apply(mat, poly)
|
||||
|
@ -1101,12 +1108,12 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
|
|||
];
|
||||
|
||||
vnf = vnf_vertex_array(
|
||||
points, col_wrap=true, caps=true, reverse=true,
|
||||
style=(abs(higbee1)+abs(higbee2))>0? "quincunx" : "alt"
|
||||
points, col_wrap=true, caps=true, reverse=true,
|
||||
style=higbee1>0 || higbee2>0 ? "quincunx" : "alt"
|
||||
);
|
||||
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
||||
vnf_polyhedron(vnf, convexity=2*twist/360);
|
||||
vnf_polyhedron(vnf, convexity=ceil(2*twist/360));
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
// For specific thread types use other modules that supply the appropriate profile.
|
||||
// .
|
||||
// You give the profile as a 2D path that will be scaled by the pitch to produce the final thread shape. The profile X values
|
||||
// must be between -1/2 and 1/2. The Y value is 0 at the peak and, due to scaling by the pitch, `-depth/pitch` in the valleys. The segment between the end
|
||||
// must be between -1/2 and 1/2. The Y=0 point will align with the specified rod diameter, so generally you want a Y value of zero at the peak (which
|
||||
// makes your specified diameter the outer diameter of the threads).
|
||||
// The value in the valleys of the thread should then be `-depth/pitch` due to the scaling by the thread pitch. The segment between the end
|
||||
// of one thread and the start of the next is added automatically, so you should not have the path start and end at equivalent points (X = ±1/2 with the same Y value).
|
||||
// Generally you should center the profile horizontally in the interval [-1/2, 1/2].
|
||||
// .
|
||||
|
@ -99,7 +101,6 @@ module generic_threaded_rod(
|
|||
_r1 = r1 * rsc + islop;
|
||||
_r2 = r2 * rsc + islop;
|
||||
threads = quantup(l/pitch+2,1); // Was quantup(1/pitch+2,2*starts);
|
||||
echo(threads=threads);
|
||||
dir = left_handed? -1 : 1;
|
||||
twist = 360 * l / pitch / starts;
|
||||
higang1 = first_defined([higbee1, higbee, 0]);
|
||||
|
@ -141,7 +142,6 @@ module generic_threaded_rod(
|
|||
: (higang2==0 && tang>=0)? 1
|
||||
: lookup(tang, hig_table),
|
||||
higscale = yscale(hsc,cp = -pdepth) // Scale for higbee
|
||||
//,eff=echo(tang=tang, twist=twist)
|
||||
)
|
||||
// The right movement finds the position of the thread along
|
||||
// what will be the z axis after the profile is mapped to 3d
|
||||
|
@ -261,7 +261,6 @@ module generic_threaded_nut(
|
|||
slope = (id2-id1)/h;
|
||||
full_id1 = id1-slope*extra/2;
|
||||
full_id2 = id2+slope*extra/2;
|
||||
echo(id1=full_id1,id2=full_id2);
|
||||
bevel1 = first_defined([bevel1,bevel,false]);
|
||||
bevel2 = first_defined([bevel2,bevel,false]);
|
||||
dummy1 = assert(is_num(pitch) && pitch>0);
|
||||
|
@ -288,14 +287,21 @@ module generic_threaded_nut(
|
|||
|
||||
// Module: thread_helix()
|
||||
// Usage:
|
||||
// thread_helix(d, pitch, thread_depth, [thread_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]);
|
||||
// thread_helix(d, pitch, [thread_depth], [flank_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]);
|
||||
// Description:
|
||||
// Creates a helical thread with optional end tapering.
|
||||
// Creates a right-handed helical thread with optional end tapering. You can specify a thread_depth and flank_angle, in which
|
||||
// case you get a symmetric trapezoidal thread, whose base is at the diameter (so the total diameter will be d + thread_depth).
|
||||
// Atlernatively you can give a profile, following the same rules as for general_threaded_rod.
|
||||
// The Y=0 point will align with the specified diameter, and the profile should
|
||||
// range in X from -1/2 to 1/2. You cannot specify both the profile and the thread_depth or flank_angle.
|
||||
// .
|
||||
// Higbee specifies tapering applied to the ends of the extrusion and is given as the linear distance
|
||||
// over which to taper.
|
||||
// Arguments:
|
||||
// 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. Default: 15 degrees.
|
||||
// flank_angle = Angle of thread faces to plane perpendicular to screw. 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.
|
||||
|
@ -321,35 +327,39 @@ module generic_threaded_nut(
|
|||
// ];
|
||||
// stroke(profile, width=0.02);
|
||||
// Example:
|
||||
// thread_helix(d=10, pitch=2, thread_depth=0.75, thread_angle=15, twist=900, $fn=72);
|
||||
// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, twist=900, $fn=72);
|
||||
module thread_helix(
|
||||
d, pitch=2, thread_depth, thread_angle=15, twist=720,
|
||||
d, pitch, thread_depth, flank_angle, twist=720,
|
||||
profile, starts=1, left_handed=false, internal=false,
|
||||
d1, d2, higbee, higbee1, higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile");
|
||||
h = pitch*starts*twist/360;
|
||||
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? [
|
||||
profile = is_def(profile) ? profile :
|
||||
let(
|
||||
tdp = thread_depth / pitch,
|
||||
dz = tdp * tan(flank_angle),
|
||||
cap = (1 - 2*dz)/2
|
||||
)
|
||||
internal?
|
||||
[
|
||||
[-cap/2-dz, tdp],
|
||||
[-cap/2, 0 ],
|
||||
[+cap/2, 0 ],
|
||||
[+cap/2+dz, tdp],
|
||||
] : [
|
||||
]
|
||||
:
|
||||
[
|
||||
[+cap/2+dz, 0 ],
|
||||
[+cap/2, tdp],
|
||||
[-cap/2, tdp],
|
||||
[-cap/2-dz, 0 ],
|
||||
]
|
||||
);
|
||||
];
|
||||
pline = mirror([-1,1], p = profile * pitch);
|
||||
dir = left_handed? -1 : 1;
|
||||
idir = internal? -1 : 1;
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
||||
zrot_copies(n=starts) {
|
||||
spiral_sweep(pline, h=h, r1=r1, r2=r2, twist=twist*dir, higbee=higbee, higbee1=higbee1, higbee2=higbee2, internal=internal, anchor=CENTER);
|
||||
|
|
Loading…
Reference in a new issue