mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-30 08:19:36 +00:00
commit
285e7cf4d3
5 changed files with 1497 additions and 993 deletions
243
bottlecaps.scad
243
bottlecaps.scad
|
@ -9,7 +9,8 @@
|
|||
|
||||
include <threading.scad>
|
||||
include <knurling.scad>
|
||||
|
||||
include <structs.scad>
|
||||
include <rounding.scad>
|
||||
|
||||
// Section: PCO-1810 Bottle Threading
|
||||
|
||||
|
@ -53,7 +54,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 +114,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 +165,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 +193,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 +247,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 +307,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 +377,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 +429,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 +479,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 +528,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 +546,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 +588,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 +599,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 +690,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
|
||||
);
|
||||
|
@ -948,4 +949,216 @@ function bottle_adapter_neck_to_neck(
|
|||
|
||||
|
||||
|
||||
// Section: SPI Bottle Threading
|
||||
|
||||
|
||||
// Module: sp_neck()
|
||||
// Usage:
|
||||
// sp_neck(diam, type, wall|id, [style], [bead], [anchor], [spin], [orient])
|
||||
// Description:
|
||||
// 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
|
||||
// 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
|
||||
// neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
|
||||
// You can also choose between the L style thread, which is symmetric and
|
||||
// the M style thread, which is an asymmetric buttress thread. You can
|
||||
// specify the wall thickness (measured from the base of the threads) or
|
||||
// the inner diameter, and you can specify an optional bead at the base of the threads.
|
||||
// Arguments:
|
||||
// diam = nominal outer diameter of threads
|
||||
// type = thread type, one of 400, 410 and 415
|
||||
// wall = wall thickness
|
||||
// ---
|
||||
// id = inner diameter
|
||||
// style = Either "L" or "M" to specify the thread style. Default: "L"
|
||||
// bead = if true apply a bad to the neck. Default: false
|
||||
// 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`
|
||||
// Examples:
|
||||
// sp_neck(48,400,2);
|
||||
// sp_neck(48,400,2,bead=true);
|
||||
// sp_neck(22,410,2);
|
||||
// sp_neck(22,410,2,bead=true);
|
||||
// sp_neck(28,415,id=20,style="M");
|
||||
// sp_neck(13,415,wall=1,style="M",bead=true);
|
||||
|
||||
|
||||
// Thread specs from https://www.isbt.com/threadspecs-downloads.asp
|
||||
|
||||
_sp_specs = [
|
||||
[400, //diam T I H S tpi
|
||||
[[ 18, [ 17.68, 8.26, 9.42, 0.94, 8]],
|
||||
[ 20, [ 19.69, 10.26, 9.42, 0.94, 8]],
|
||||
[ 22, [ 21.69, 12.27, 9.42, 0.94, 8]],
|
||||
[ 24, [ 23.67, 13.11, 10.16, 1.17, 8]],
|
||||
[ 28, [ 27.38, 15.60, 10.16, 1.17, 6]],
|
||||
[ 30, [ 28.37, 16.59, 10.24, 1.17, 6]],
|
||||
[ 33, [ 31.83, 20.09, 10.24, 1.17, 6]],
|
||||
[ 35, [ 34.34, 22.23, 10.24, 1.17, 6]],
|
||||
[ 38, [ 37.19, 25.07, 10.24, 1.17, 6]],
|
||||
[ 40, [ 39.75, 27.71, 10.24, 1.17, 6]],
|
||||
[ 43, [ 41.63, 29.59, 10.24, 1.17, 6]],
|
||||
[ 45, [ 43.82, 31.78, 10.24, 1.17, 6]],
|
||||
[ 48, [ 47.12, 35.08, 10.24, 1.17, 6]],
|
||||
[ 51, [ 49.56, 37.57, 10.36, 1.17, 6]],
|
||||
[ 53, [ 52.07, 40.08, 10.36, 1.17, 6]],
|
||||
[ 58, [ 56.06, 44.07, 10.36, 1.17, 6]],
|
||||
[ 60, [ 59.06, 47.07, 10.36, 1.17, 6]],
|
||||
[ 63, [ 62.08, 50.09, 10.36, 1.17, 6]],
|
||||
[ 66, [ 65.07, 53.09, 10.36, 1.17, 6]],
|
||||
[ 70, [ 69.06, 57.07, 10.36, 1.17, 6]],
|
||||
[ 75, [ 73.56, 61.57, 10.36, 1.17, 6]],
|
||||
[ 77, [ 76.66, 64.67, 12.37, 1.52, 6]],
|
||||
[ 83, [ 82.58, 69.93, 12.37, 1.52, 5]],
|
||||
[ 89, [ 88.75, 74.12, 13.59, 1.52, 5]],
|
||||
[100, [ 99.57, 84.94, 15.16, 1.52, 5]],
|
||||
[110, [109.58, 94.92, 15.16, 1.52, 5]],
|
||||
[120, [119.56,104.93, 17.40, 1.52, 5]],
|
||||
]],
|
||||
[410, //diam T I H S tpi L W
|
||||
[[ 18, [ 17.68, 8.26, 13.28, 0.94, 8, 9.17, 2.13]],
|
||||
[ 20, [ 19.59, 10.26, 14.07, 0.94, 8, 9.17, 2.13]],
|
||||
[ 22, [ 21.69, 12.27, 14.86, 0.94, 8, 9.55, 2.13]],
|
||||
[ 24, [ 23.67, 13.11, 16.41, 1.17, 8, 11.10, 2.13]],
|
||||
[ 28, [ 27.38, 15.60, 17.98, 1.17, 6, 11.76, 2.39]],
|
||||
]],
|
||||
[415, //diam T I H S tpi L W
|
||||
[[ 13, [ 12.90, 5.54, 11.48, 0.94,12, 7.77, 1.14]],
|
||||
[ 15, [ 14.61, 6.55, 14.15, 0.94,12, 8.84, 1.14]],
|
||||
[ 18, [ 17.68, 8.26, 15.67, 0.94, 8, 10.90, 2.13]],
|
||||
[ 20, [ 19.69, 10.26, 18.85, 0.94, 8, 11.58, 2.13]],
|
||||
[ 22, [ 21.69, 12.27, 21.26, 0.94, 8, 13.87, 2.13]],
|
||||
[ 24, [ 23.67, 13.11, 24.31, 1.17, 8, 14.25, 2.13]],
|
||||
[ 28, [ 27.38, 15.60, 27.48, 1.17, 6, 16.64, 2.39]],
|
||||
[ 33, [ 31.83, 20.09, 32.36, 1.17, 6, 19.61, 2.39]],
|
||||
]]
|
||||
];
|
||||
|
||||
_sp_twist = [ [400, 360],
|
||||
[410, 540],
|
||||
[415, 720]
|
||||
];
|
||||
|
||||
|
||||
// profile data: tpi, total width, depth,
|
||||
_sp_thread_width= [
|
||||
[5, 3.05],
|
||||
[6, 2.39],
|
||||
[8, 2.13],
|
||||
[12, 1.14], // But note style M is different
|
||||
];
|
||||
|
||||
|
||||
function _sp_thread_profile(tpi, a, S, style) =
|
||||
let(
|
||||
pitch = 1/tpi*INCH,
|
||||
cL = a*(1-1/sqrt(3)),
|
||||
cM = (1-tan(10))*a/2,
|
||||
// SP specified roundings for the thread profile have special case for tpi=12
|
||||
roundings = style=="L" && tpi < 12 ? 0.5
|
||||
: style=="M" && tpi < 12 ? [0.25, 0.25, 0.75, 0.75]
|
||||
: style=="L" ? [0.38, 0.13, 0.13, 0.38]
|
||||
: /* style=="M" */ [0.25, 0.25, 0.2, 0.5],
|
||||
path = style=="L"
|
||||
? round_corners([[-1/2*pitch,-a/2],
|
||||
[-a/2,-a/2],
|
||||
[-cL/2,0],
|
||||
[cL/2,0],
|
||||
[a/2,-a/2],
|
||||
[1/2*pitch,-a/2]], radius=roundings, closed=false,$fn=24)
|
||||
: round_corners(
|
||||
[[-1/2*pitch,-a/2],
|
||||
[-a/2, -a/2],
|
||||
[-cM, 0],
|
||||
[0,0],
|
||||
[a/2,-a/2],
|
||||
[1/2*pitch,-a/2]], radius=roundings, closed=false, $fn=24)
|
||||
)
|
||||
// Shift so that the profile is S mm from the right end to create proper length S top gap
|
||||
select(right(-a/2+1/2-S,p=path),1,-2)/pitch;
|
||||
|
||||
|
||||
function sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) = no_function("sp_neck");
|
||||
module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
||||
{
|
||||
assert(num_defined([wall,id])==1, "Must define exactly one of wall and id");
|
||||
|
||||
table = struct_val(_sp_specs,type);
|
||||
dum1=assert(is_def(table),"Unknown SP closure type. Type must be one of 400, 410, or 415");
|
||||
entry = struct_val(table, diam);
|
||||
dum2=assert(is_def(entry), str("Unknown closure nominal diameter. Allowed diameters for SP",type,": ",struct_keys(table)))
|
||||
assert(style=="L" || style=="M", "style must be \"L\" or \"M\"");
|
||||
|
||||
T = entry[0];
|
||||
I = entry[1];
|
||||
H = entry[2];
|
||||
S = entry[3];
|
||||
tpi = entry[4];
|
||||
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
|
||||
|
||||
twist = struct_val(_sp_twist, type);
|
||||
|
||||
profile = _sp_thread_profile(tpi,a,S,style);
|
||||
|
||||
depth = a/2;
|
||||
higlen = 2*a;
|
||||
higang = higlen / ((T-2*depth)*PI) * 360;
|
||||
|
||||
beadmax = type==400 ? (T/2-depth)+depth*1.25
|
||||
: diam <=15 ? (T-.15)/2 : (T-.05)/2;
|
||||
|
||||
W = type==400 ? a*1.5 // arbitrary decision for type 400
|
||||
: entry[6]; // specified width for 410 and 415
|
||||
|
||||
beadpts = [
|
||||
[0,-W/2],
|
||||
each arc(16, points = [[T/2-depth, -W/2],
|
||||
[beadmax, 0],
|
||||
[T/2-depth, W/2]]),
|
||||
[0,W/2]
|
||||
];
|
||||
|
||||
isect400 = [for(seg=pair(beadpts)) let(segisect = line_segment_intersection([[T/2,0],[T/2,1]] , seg)) if (is_def(segisect)) segisect.y];
|
||||
|
||||
extra_bot = type==400 && bead ? -min(subindex(beadpts,1))+max(isect400) : 0;
|
||||
bead_shift = type==400 ? H+max(isect400) : entry[5]+W/2; // entry[5] is L
|
||||
|
||||
attachable(anchor,spin,orient,r=bead ? beadmax : T/2, l=H+extra_bot){
|
||||
up((H+extra_bot)/2){
|
||||
difference(){
|
||||
union(){
|
||||
thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, twist=twist+2*higang, higbee=higlen, anchor=TOP);
|
||||
cylinder(d=T-depth*2,l=H,anchor=TOP);
|
||||
if (bead)
|
||||
down(bead_shift)
|
||||
rotate_extrude()
|
||||
polygon(beadpts);
|
||||
}
|
||||
up(.5)cyl(d=is_def(id) ? id : T-a-2*wall, l=H-extra_bot+1, anchor=TOP);
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Function: sp_diameter()
|
||||
// Usage:
|
||||
// true_diam = sp_diameter(diam,type)
|
||||
// Description:
|
||||
// Returns the actual base diameter (root of the threads) for a SPI plastic bottle neck given the nominal diameter and type number (400, 410, 415).
|
||||
function sp_diameter(diam,type) =
|
||||
let(
|
||||
table = struct_val(_sp_specs,type)
|
||||
)
|
||||
assert(is_def(table),"Unknown SP closure type. Type must be one of 400, 410, or 415")
|
||||
let(
|
||||
entry = struct_val(table, diam)
|
||||
)
|
||||
assert(is_def(entry), str("Unknown closure nominal diameter. Allowed diameters for SP",type,": ",struct_keys(table)))
|
||||
entry[0];
|
||||
|
||||
|
||||
|
||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||
|
|
87
paths.scad
87
paths.scad
|
@ -1030,8 +1030,12 @@ 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 3D spiral path
|
||||
// of a given radius, height and twist. The origin in the profile traces out the helix of the specified radius.
|
||||
// If twist is positive the path will be right-handed; if twist 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
|
||||
// over which to taper.
|
||||
// Arguments:
|
||||
// poly = Array of points of a polygon path, to be extruded.
|
||||
// h = height of the spiral to extrude along.
|
||||
|
@ -1040,6 +1044,9 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
|||
// ---
|
||||
// d = Diameter of the spiral to extrude along.
|
||||
// higbee = Length to taper thread ends over.
|
||||
// higbee1 = Taper length at start
|
||||
// higbee2 = Taper length at end
|
||||
// internal = direction to taper the threads with higbee. If true threads taper outward; if false they taper inward. Default: false
|
||||
// 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`
|
||||
|
@ -1047,57 +1054,67 @@ 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, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, anchor, spin=0, orient=UP) {
|
||||
poly = path3d(poly);
|
||||
module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor, spin=0, orient=UP) {
|
||||
higsample = 10; // Oversample factor for higbee tapering
|
||||
dummy1=assert(is_num(twist) && twist != 0);
|
||||
bounds = pointlist_bounds(poly);
|
||||
yctr = (bounds[0].y+bounds[1].y)/2;
|
||||
xmin = bounds[0].x;
|
||||
xmax = bounds[1].x;
|
||||
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);
|
||||
sides = segs(max(r1,r2));
|
||||
steps = ceil(sides*(twist/360));
|
||||
dir = sign(twist);
|
||||
ang_step = 360/sides*dir;
|
||||
anglist = [for(ang = [0:ang_step:twist-EPSILON]) ang,
|
||||
twist];
|
||||
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);
|
||||
|
||||
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);
|
||||
dummy2=assert(higbee1>=0 && higbee2>=0)
|
||||
assert(higang1 < dir*twist/2,"Higbee1 is more than half the threads")
|
||||
assert(higang2 < dir*twist/2,"Higbee2 is more than half the threads");
|
||||
function polygon_r(N,theta) =
|
||||
let( alpha = 360/N )
|
||||
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
||||
higofs = pow(0.05,2); // Smallest hig scale is the square root of this value
|
||||
function taperfunc(x) = sqrt((1-higofs)*x+higofs);
|
||||
interp_ang = [
|
||||
for(i=idx(anglist,e=-2))
|
||||
each lerpn(anglist[i],anglist[i+1],
|
||||
(higang1>0 && higang1>dir*anglist[i+1]
|
||||
|| (higang2>0 && higang2>dir*(twist-anglist[i]))) ? ceil((anglist[i+1]-anglist[i])/ang_step*higsample)
|
||||
: 1,
|
||||
endpoint=false),
|
||||
last(anglist)
|
||||
];
|
||||
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h));
|
||||
points = [
|
||||
for (p = us) let (
|
||||
u = p / steps,
|
||||
a = twist * u,
|
||||
hsc = higsize(a),
|
||||
for (a = interp_ang) let (
|
||||
hsc = dir*a<higang1 ? taperfunc(dir*a/higang1)
|
||||
: dir*(twist-a)<higang2 ? taperfunc(dir*(twist-a)/higang2)
|
||||
: 1,
|
||||
u = a/twist,
|
||||
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]),
|
||||
mat = affine3d_zrot(a)
|
||||
* affine3d_translate([polygon_r(sides,a)*r, 0, h * (u-0.5)])
|
||||
* affine3d_xrot(90)
|
||||
* skewmat
|
||||
* scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
|
||||
pts = apply(mat, poly)
|
||||
) pts
|
||||
];
|
||||
|
||||
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=dir>0?true:false,
|
||||
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*dir*twist/360));
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
|
74
screws.scad
74
screws.scad
|
@ -837,18 +837,18 @@ module screw_head(screw_info,details=false) {
|
|||
// anchor = anchor relative to the shaft of the screw
|
||||
// anchor_head = anchor relative to the screw head
|
||||
// Example(Med): Selected UTS (English) screws
|
||||
// $fn=32;
|
||||
// xdistribute(spacing=8){
|
||||
// screw("#6", length=12);
|
||||
// screw("#6-32", head="button", drive="torx",length=12);
|
||||
// screw("#6-32,3/4", head="hex");
|
||||
// screw("#6", thread="fine", head="fillister",length=12, drive="phillips");
|
||||
// screw("#6", head="flat small",length=12,drive="slot");
|
||||
// screw("#6-32", head="flat large", length=12, drive="torx");
|
||||
// screw("#6-32", head="flat undercut",length=12);
|
||||
// screw("#6-24", head="socket",length=12); // Non-standard threading
|
||||
// screw("#6-32", drive="hex", drive_size=1.5, length=12);
|
||||
// }
|
||||
$fn=32;
|
||||
xdistribute(spacing=8){
|
||||
screw("#6", length=12);
|
||||
screw("#6-32", head="button", drive="torx",length=12);
|
||||
screw("#6-32,3/4", head="hex");
|
||||
screw("#6", thread="fine", head="fillister",length=12, drive="phillips");
|
||||
screw("#6", head="flat small",length=12,drive="slot");
|
||||
screw("#6-32", head="flat large", length=12, drive="torx");
|
||||
screw("#6-32", head="flat undercut",length=12);
|
||||
screw("#6-24", head="socket",length=12); // Non-standard threading
|
||||
screw("#6-32", drive="hex", drive_size=1.5, length=12);
|
||||
}
|
||||
// Example(Med): A few examples of ISO (metric) screws
|
||||
// $fn=32;
|
||||
// xdistribute(spacing=8){
|
||||
|
@ -1243,38 +1243,30 @@ function thread_specification(screw_spec, internal=false, tolerance=undef) =
|
|||
function _thread_profile(thread) =
|
||||
let(
|
||||
pitch = struct_val(thread,"pitch"),
|
||||
basicrad = struct_val(thread,"basic")/2,
|
||||
meanpitchrad = mean(struct_val(thread,"d_pitch"))/2,
|
||||
meanminorrad = mean(struct_val(thread,"d_minor"))/2,
|
||||
meanmajorrad = mean(struct_val(thread,"d_major"))/2,
|
||||
depth = (meanmajorrad-meanminorrad)/pitch,
|
||||
crestwidth = (pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3))/pitch
|
||||
|
||||
depth = meanmajorrad-meanminorrad,
|
||||
crestwidth = pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3)
|
||||
)
|
||||
[
|
||||
[-depth/sqrt(3)-crestwidth/2, -depth],
|
||||
[ -crestwidth/2, 0],
|
||||
[ crestwidth/2, 0],
|
||||
[ depth/sqrt(3)+crestwidth/2, -depth]
|
||||
]/pitch;
|
||||
|
||||
|
||||
/* Old non-centered profile
|
||||
|
||||
[
|
||||
[-1/2,-depth],
|
||||
[depth/sqrt(3)-1/2,0],
|
||||
[depth/sqrt(3)+crestwidth-1/2, 0],
|
||||
[crestwidth + 2*depth/sqrt(3)-1/2,-depth]
|
||||
];
|
||||
|
||||
function _thread_profile_e(thread) =
|
||||
let(
|
||||
pitch = struct_val(thread,"pitch"),
|
||||
basicrad = struct_val(thread,"basic")/2,
|
||||
meanpitchrad = mean(struct_val(thread,"d_pitch"))/2,
|
||||
meanminorrad = mean(struct_val(thread,"d_minor"))/2,
|
||||
meanmajorrad = mean(struct_val(thread,"d_major"))/2,
|
||||
depth = (meanmajorrad-meanminorrad)/pitch,
|
||||
crestwidth = (pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3))/pitch
|
||||
|
||||
)
|
||||
[
|
||||
[-1/2,-1], // -1 instead of -depth?
|
||||
[depth/sqrt(3)-1/2,0],
|
||||
[depth/sqrt(3)+crestwidth-1/2, 0],
|
||||
[crestwidth + 2*depth/sqrt(3)-1/2,-1]
|
||||
];
|
||||
]
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
module _rod(spec, length, tolerance, orient=UP, spin=0, anchor=CENTER)
|
||||
|
@ -1283,11 +1275,19 @@ module _rod(spec, length, tolerance, orient=UP, spin=0, anchor=CENTER)
|
|||
echo(d_major_mean = mean(struct_val(threadspec, "d_major")));
|
||||
echo(bolt_profile=_thread_profile(threadspec));
|
||||
|
||||
trapezoidal_threaded_rod( d=mean(struct_val(threadspec, "d_major")),
|
||||
threaded_rod([mean(struct_val(threadspec, "d_minor")),
|
||||
mean(struct_val(threadspec, "d_pitch")),
|
||||
mean(struct_val(threadspec, "d_major"))],
|
||||
pitch = struct_val(threadspec, "pitch"),
|
||||
l=length, left_handed=false,
|
||||
bevel=false, orient=orient, anchor=anchor, spin=spin);
|
||||
/*
|
||||
generic_threaded_rod( d=mean(struct_val(threadspec, "d_major")),
|
||||
l=length,
|
||||
pitch = struct_val(threadspec, "pitch"),
|
||||
profile = _thread_profile(threadspec),left_handed=false,
|
||||
bevel=false, orient=orient, anchor=anchor, spin=spin);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -1352,7 +1352,7 @@ module nut(name, diameter, thickness, thread="coarse", oversize=0, spec, toleran
|
|||
threadspec = thread_specification(spec, internal=true, tolerance=tolerance);
|
||||
echo(threadspec=threadspec,"for nut threads");
|
||||
echo(nut_minor_diam = mean(struct_val(threadspec,"d_minor")));
|
||||
trapezoidal_threaded_nut(
|
||||
generic_threaded_nut(
|
||||
od=diameter, id=mean(struct_val(threadspec, "d_major")), h=thickness,
|
||||
pitch=struct_val(threadspec, "pitch"),
|
||||
profile=_thread_profile(threadspec),
|
||||
|
|
2084
threading.scad
2084
threading.scad
File diff suppressed because it is too large
Load diff
2
vnf.scad
2
vnf.scad
|
@ -216,7 +216,7 @@ function vnf_triangulate(vnf) =
|
|||
|
||||
// Function: vnf_vertex_array()
|
||||
// Usage:
|
||||
// vnf = vnf_vertex_array(points, [caps], [cap1], [cap2], [reverse], [col_wrap], [row_wrap], [vnf]);
|
||||
// vnf = vnf_vertex_array(points, [caps], [cap1], [cap2], [style], [reverse], [col_wrap], [row_wrap], [vnf]);
|
||||
// Description:
|
||||
// Creates a VNF structure from a vertex list, by dividing the vertices into columns and rows,
|
||||
// adding faces to tile the surface. You can optionally have faces added to wrap the last column
|
||||
|
|
Loading…
Reference in a new issue