mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09:45 +00:00
commit
0b4a961d14
9 changed files with 286 additions and 138 deletions
|
@ -1144,7 +1144,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
|
||||
// Module: sp_cap()
|
||||
// Usage:
|
||||
// sp_neck(cap, type, wall, [style=], [top_adj=], [bot_adj=], [$slop]) [ATTACHMENTS];
|
||||
// sp_cap(diam, type, wall, [style=], [top_adj=], [bot_adj=], [$slop]) [ATTACHMENTS];
|
||||
// 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
|
||||
|
|
19
masks3d.scad
19
masks3d.scad
|
@ -98,7 +98,7 @@ module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
|||
// chamfer = Size of the edge chamfered, inset from edge.
|
||||
// ---
|
||||
// d = Diameter of cylinder to chamfer. Use instead of r.
|
||||
// ang = Angle of chamfer in degrees from vertical. (Default: 45)
|
||||
// ang = Angle of chamfer in degrees from the horizontal. (Default: 45)
|
||||
// from_end = If true, chamfer size is measured from end of cylinder. If false, chamfer is measured outset from the radius of the cylinder. (Default: false)
|
||||
// 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`
|
||||
|
@ -113,12 +113,27 @@ module chamfer_corner_mask(chamfer=1, anchor=CENTER, spin=0, orient=UP) {
|
|||
// cylinder(r=50, h=100, center=true);
|
||||
// up(50) chamfer_cylinder_mask(r=50, chamfer=10);
|
||||
// }
|
||||
// Example: Changing the chamfer angle
|
||||
// difference() {
|
||||
// cylinder(r=50, h=100, center=true);
|
||||
// up(50) #chamfer_cylinder_mask(r=50, chamfer=10, ang=70);
|
||||
// }
|
||||
// Example:
|
||||
// difference() {
|
||||
// cylinder(r=50, h=100, center=true);
|
||||
// up(50) chamfer_cylinder_mask(r=50, chamfer=10, ang=70);
|
||||
// }
|
||||
// Example: Masking by Attachment
|
||||
// diff()
|
||||
// cyl(d=100,h=40)
|
||||
// attach([TOP,BOT])
|
||||
// tag("remove")chamfer_cylinder_mask(d=100, chamfer=10);
|
||||
function chamfer_cylinder_mask(r, chamfer, d, ang=45, from_end=false, anchor=CENTER, spin=0, orient=UP) = no_function("chamfer_cylinder_mask");
|
||||
module chamfer_cylinder_mask(r, chamfer, d, ang=45, from_end=false, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
ch = from_end? chamfer : opp_ang_to_adj(chamfer,ang);
|
||||
dummy = assert(all_nonnegative([chamfer]), "Chamfer must be a nonnegative number");
|
||||
ch = from_end? chamfer : opp_ang_to_adj(chamfer,90-ang);
|
||||
attachable(anchor,spin,orient, r=r, l=ch*2) {
|
||||
difference() {
|
||||
cyl(r=r+chamfer, l=ch*2, anchor=CENTER);
|
||||
|
|
|
@ -101,7 +101,7 @@ function lerp(a,b,u) =
|
|||
// Description:
|
||||
// Returns exactly `n` values, linearly interpolated between `a` and `b`.
|
||||
// If `endpoint` is true, then the last value will exactly equal `b`.
|
||||
// If `endpoint` is false, then the last value will about `a+(b-a)*(1-1/n)`.
|
||||
// If `endpoint` is false, then the last value will be `a+(b-a)*(1-1/n)`.
|
||||
// Arguments:
|
||||
// a = First value or vector.
|
||||
// b = Second value or vector.
|
||||
|
|
24
screws.scad
24
screws.scad
|
@ -207,8 +207,8 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
|||
// Figure(2D,Med,VPD = 140, VPT = [18.4209, 14.9821, -3.59741], VPR = [0, 0, 0],NoAxes):
|
||||
// rpos=33;
|
||||
// fsize=2.5;
|
||||
// projection(cut=true) xrot(-90)screw("M8", head="socket", length=25, thread_len=10);
|
||||
// right(rpos)projection(cut=true) xrot(-90)screw("M8", head="flat", length=25, thread_len=10);
|
||||
// projection(cut=true) xrot(-90)screw("M8", head="socket", length=25, thread_len=10,anchor=BOT);
|
||||
// right(rpos)projection(cut=true) xrot(-90)screw("M8", head="flat", length=25, thread_len=10,anchor=BOT);
|
||||
// color("black"){
|
||||
// stroke([[5,0],[5,10]],endcaps="arrow2",width=.3);
|
||||
// back(5)right(6)text("threads",size=fsize,anchor=LEFT);
|
||||
|
@ -241,6 +241,10 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
|||
// undersize = amount to decrease screw diameter, a scalar to apply to all parts, or a 2-vector to control shaft and head. Default: 0
|
||||
// undersize_shaft = amount to decrease diameter of the shaft of screw
|
||||
// undersize_head = amount to decrease the head diameter of the screw
|
||||
// bevel1 = bevel bottom end of screw. Default: true
|
||||
// bevel2 = bevel top end of threaded section. Default: true for headless, false otherwise
|
||||
// bevel = bevel both ends of the threaded section.
|
||||
// higbee = if true create blunt start threads at both ends for headless screws, and bottom only for other screws. Default: false
|
||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
||||
// anchor = Translate so anchor point on the shaft 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`
|
||||
|
@ -503,7 +507,9 @@ function screw(spec, head, drive, thread, drive_size,
|
|||
length, l, thread_len, tolerance, details=true,
|
||||
undersize, shaft_undersize, head_undersize,
|
||||
atype="screw",anchor=BOTTOM, spin=0, orient=UP,
|
||||
_shoulder_diam=0, _shoulder_len=0,
|
||||
_shoulder_diam=0, _shoulder_len=0,
|
||||
bevel,bevel1,bevel2,bevelsize,
|
||||
higbee=false,
|
||||
_internal=false, _counterbore, _teardrop) = no_function("screw");
|
||||
|
||||
module screw(spec, head, drive, thread, drive_size,
|
||||
|
@ -512,6 +518,7 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
atype="screw",anchor, spin=0, orient=UP,
|
||||
_shoulder_diam=0, _shoulder_len=0,
|
||||
bevel,bevel1,bevel2,bevelsize,
|
||||
higbee,
|
||||
_internal=false, _counterbore, _teardrop=false)
|
||||
{
|
||||
tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw",
|
||||
|
@ -674,6 +681,8 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
l=thread_len+eps_thread, left_handed=false, internal=_internal,
|
||||
bevel1=bev1,
|
||||
bevel2=bev2,
|
||||
higbee1=higbee && !_internal,
|
||||
higbee2=(!headless && !_internal) || is_undef(higbee) ? false : higbee,
|
||||
$fn=sides, anchor=TOP);
|
||||
}
|
||||
|
||||
|
@ -737,6 +746,7 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
// bevel = if true create bevel at both ends of hole. Default: see below
|
||||
// bevel1 = if true create bevel at bottom end of hole. Default: false
|
||||
// bevel2 = if true create bevel at top end of hole. Default: true when tolerance="self tap", false otherwise
|
||||
// higbee = if true and hole is threaded, create blunt start threads at the top of the hole. Default: false
|
||||
// $slop = add extra gap to account for printer overextrusion. Default: 0
|
||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
||||
// anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -1463,6 +1473,9 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,oversize=0
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// tolerance = nut tolerance. Determines actual nut thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and "6H" for ISO.
|
||||
// $slop = extra space left to account for printing over-extrusion. Default: 0
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -1508,10 +1521,10 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,oversize=0
|
|||
// nut("#8", thread="none");
|
||||
|
||||
function nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
= no_function("nut");
|
||||
module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
{
|
||||
dummyA = assert(is_undef(nutwidth) || (is_num(nutwidth) && nutwidth>0));
|
||||
|
||||
|
@ -1539,6 +1552,7 @@ module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
|||
shape=shape,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang,
|
||||
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor,spin=spin,orient=orient) children();
|
||||
}
|
||||
|
||||
|
|
103
shapes3d.scad
103
shapes3d.scad
|
@ -1172,7 +1172,35 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
// Creates cylinders in various anchorings and orientations, with optional rounding, chamfers, or textures.
|
||||
// You can use `h` and `l` interchangably, and all variants allow specifying size by either `r`|`d`,
|
||||
// or `r1`|`d1` and `r2`|`d2`. Note: the chamfers and rounding cannot be cumulatively longer than
|
||||
// the cylinder's length.
|
||||
// the cylinder or cone's sloped side. The more specific parameters like chamfer1 or rounding2 override the more
|
||||
// general ones like chamfer or rounding, so if you specify `rounding=3, chamfer2=3` you will get a chamfer at the top and
|
||||
// rounding at the bottom.
|
||||
//
|
||||
|
||||
// Figure(2D,Med): Chamfers on cones can be tricky. This figure shows chamfers of the same size and same angle, A=30 degrees. Note that the angle is measured on the inside, and produces a quit different looking chamfer at the top and bottom of the cone. Black arrows mark the size of the chamfers, which may not even appear the same size visually. When you do not give an angle, the triangle that is cut off will be isoceles, like the triangle at the top, with two equal angles.
|
||||
// color("lightgray")
|
||||
// projection()
|
||||
// cyl(r2=10, r1=20, l=20,chamfang=30, chamfer=0,orient=BACK);
|
||||
// projection()
|
||||
// cyl(r2=10, r1=20, l=20,chamfang=30, chamfer=8,orient=BACK);
|
||||
// color("black"){
|
||||
// fwd(9.8)right(20-5.5)text("A",size=1.1);
|
||||
// fwd(-8.7)right(10-5.5)text("A",size=1.1);
|
||||
// right(20-8)fwd(10.5)stroke([[0,0],[8,0]], endcaps="arrow2",width=.15);
|
||||
// right(10-8)fwd(-10.5)stroke([[0,0],[8,0]], endcaps="arrow2",width=.15);
|
||||
// }
|
||||
// Figure(2D,Med): With negative chamfers, the angle A=30 degrees is on the outside. The chamfers are again quit different looking. As before, the default will feature two congruent angles, and in this case it happens at the bottom of the cone but not the top. The arrows again show the size of the chamfer.
|
||||
// color("lightgray")
|
||||
// projection()
|
||||
// cyl(r2=10, r1=20, l=20,chamfang=30, chamfer=-8,orient=BACK);
|
||||
// projection()
|
||||
// cyl(r2=10, r1=20, l=20,chamfang=30, chamfer=0,orient=BACK);
|
||||
// color("black"){
|
||||
// fwd(9.8)right(20+4.5)text("A",size=1.1);
|
||||
// fwd(-8.7)right(10+4.3)text("A",size=1.1);
|
||||
// right(20)fwd(10.5)stroke([[0,0],[8,0]], endcaps="arrow2",width=.15);
|
||||
// right(10)fwd(-10.5)stroke([[0,0],[8,0]], endcaps="arrow2",width=.15);
|
||||
// }
|
||||
//
|
||||
// Arguments:
|
||||
// l / h = Length of cylinder along oriented axis. Default: 1
|
||||
|
@ -1369,51 +1397,66 @@ function cyl(
|
|||
? cylinder(h=l, r1=r1, r2=r2, center=true, $fn=sides)
|
||||
: let(
|
||||
vang = atan2(r1-r2,l),
|
||||
_chamf1 = first_defined([chamfer1, chamfer, 0]),
|
||||
_chamf2 = first_defined([chamfer2, chamfer, 0]),
|
||||
_chamf1 = first_defined([chamfer1, if (is_undef(rounding1)) chamfer, 0]),
|
||||
_chamf2 = first_defined([chamfer2, if (is_undef(rounding2)) chamfer, 0]),
|
||||
_fromend1 = first_defined([from_end1, from_end, false]),
|
||||
_fromend2 = first_defined([from_end2, from_end, false]),
|
||||
chang1 = first_defined([chamfang1, chamfang, 45+vang/2]),
|
||||
chang2 = first_defined([chamfang2, chamfang, 45-vang/2]),
|
||||
round1 = first_defined([rounding1, rounding, 0]),
|
||||
round2 = first_defined([rounding2, rounding, 0]),
|
||||
chang1 = first_defined([chamfang1, chamfang, 45+sign(_chamf1)*vang/2]),
|
||||
chang2 = first_defined([chamfang2, chamfang, 45-sign(_chamf2)*vang/2]),
|
||||
round1 = first_defined([rounding1, if (is_undef(chamfer1)) rounding, 0]),
|
||||
round2 = first_defined([rounding2, if (is_undef(chamfer2)) rounding, 0]),
|
||||
checks1 =
|
||||
assert(is_finite(_chamf1), "chamfer1 must be a finite number if given.")
|
||||
assert(is_finite(_chamf2), "chamfer2 must be a finite number if given.")
|
||||
assert(is_finite(chang1) && chang1>0 && chang1<90, "chamfang1 must be a number between 0 and 90 (exclusive) if given.")
|
||||
assert(is_finite(chang2) && chang2>0 && chang2<90, "chamfang2 must be a number between 0 and 90 (exclusive) if given.")
|
||||
assert(chang1<=90+vang, "chamfang1 is larger than the cone face angle")
|
||||
assert(180-chang2>=90+vang, "chamfang2 is larger than the cone face angle")
|
||||
assert(is_finite(chang1) && chang1>0, "chamfang1 must be a positive number if given.")
|
||||
assert(is_finite(chang2) && chang2>0, "chamfang2 must be a positive number if given.")
|
||||
assert(chang1<90+sign(_chamf1)*vang, "chamfang1 must be smaller than the cone face angle")
|
||||
assert(chang2<90-sign(_chamf2)*vang, "chamfang2 must be smaller than the cone face angle")
|
||||
assert(num_defined([chamfer1,rounding1])<2, "cannot define both chamfer1 and rounding1")
|
||||
assert(num_defined([chamfer2,rounding2])<2, "cannot define both chamfer2 and rounding2")
|
||||
assert(num_defined([chamfer,rounding])<2, "cannot define both chamfer and rounding")
|
||||
undef,
|
||||
chamf1r = !_chamf1? 0 : !_fromend1? _chamf1 :
|
||||
law_of_sines(a=_chamf1, A=chang1, B=180-chang1-(90-vang)),
|
||||
chamf2r = !_chamf2? 0 : !_fromend2? _chamf2 :
|
||||
law_of_sines(a=_chamf2, A=chang2, B=180-chang2-(90+vang)),
|
||||
chamf1l = !_chamf1? 0 : _fromend1? _chamf1 :
|
||||
law_of_sines(a=_chamf1, A=180-chang1-(90-vang), B=chang1),
|
||||
chamf2l = !_chamf2? 0 : _fromend2? _chamf2 :
|
||||
law_of_sines(a=_chamf2, A=180-chang2-(90+vang), B=chang2),
|
||||
chamf1r = !_chamf1? 0
|
||||
: !_fromend1? _chamf1
|
||||
: law_of_sines(a=_chamf1, A=chang1, B=180-chang1-(90-sign(_chamf2)*vang)),
|
||||
chamf2r = !_chamf2? 0
|
||||
: !_fromend2? _chamf2
|
||||
: law_of_sines(a=_chamf2, A=chang2, B=180-chang2-(90+sign(_chamf2)*vang)),
|
||||
chamf1l = !_chamf1? 0
|
||||
: _fromend1? abs(_chamf1)
|
||||
: abs(law_of_sines(a=_chamf1, A=180-chang1-(90-sign(_chamf1)*vang), B=chang1)),
|
||||
chamf2l = !_chamf2? 0
|
||||
: _fromend2? abs(_chamf2)
|
||||
: abs(law_of_sines(a=_chamf2, A=180-chang2-(90+sign(_chamf2)*vang), B=chang2)),
|
||||
facelen = adj_ang_to_hyp(l, abs(vang)),
|
||||
dy1 = abs(first_defined([chamf1l, round1, 0])),
|
||||
dy2 = abs(first_defined([chamf2l, round2, 0])),
|
||||
|
||||
cp1 = [r1,-l/2],
|
||||
cp2 = [r2,+l/2],
|
||||
roundlen1 = round1 >= 0 ? round1/tan(45-vang/2)
|
||||
: round1/tan(45+vang/2),
|
||||
roundlen2 = round2 >=0 ? round2/tan(45+vang/2)
|
||||
: round2/tan(45-vang/2),
|
||||
dy1 = abs(_chamf1 ? chamf1l : round1 ? roundlen1 : 0),
|
||||
dy2 = abs(_chamf2 ? chamf2l : round2 ? roundlen2 : 0),
|
||||
|
||||
checks2 =
|
||||
assert(is_finite(round1), "rounding1 must be a finite number if given.")
|
||||
assert(is_finite(round2), "rounding2 must be a finite number if given.")
|
||||
assert(is_finite(round1), "rounding1 must be a number if given.")
|
||||
assert(is_finite(round2), "rounding2 must be a number if given.")
|
||||
assert(chamf1r <= r1, "chamfer1 is larger than the r1 radius of the cylinder.")
|
||||
assert(chamf2r <= r2, "chamfer2 is larger than the r2 radius of the cylinder.")
|
||||
assert(round1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.")
|
||||
assert(round2 <= r2, "rounding2 is larger than the r1 radius of the cylinder.")
|
||||
assert(dy1+dy2 <= facelen, "Sum of fillets and chamfer sizes must be less than the length of the cylinder/cone face.")
|
||||
assert(roundlen1 <= r1, "size of rounding1 is larger than the r1 radius of the cylinder.")
|
||||
assert(roundlen2 <= r2, "size of rounding2 is larger than the r2 radius of the cylinder.")
|
||||
assert(dy1+dy2 <= facelen, "Chamfers/roundings don't fit on the cylinder/cone. They exceed the length of the cylinder/cone face.")
|
||||
undef,
|
||||
path = [
|
||||
if (texture==undef) [0,-l/2],
|
||||
if (is_finite(chamf1r) && !approx(chamf1r,0))
|
||||
if (!approx(chamf1r,0))
|
||||
each [
|
||||
[r1, -l/2] + polar_to_xy(chamf1r,180),
|
||||
[r1, -l/2] + polar_to_xy(chamf1l,90+vang),
|
||||
]
|
||||
else if (is_finite(round1) && !approx(round1,0))
|
||||
each arc(r=abs(round1), corner=[[(round1>0?0:1e6),-l/2],[r1,-l/2],[r2,l/2]])
|
||||
else if (!approx(round1,0))
|
||||
each arc(r=abs(round1), corner=[[max(0,r1-2*roundlen1),-l/2],[r1,-l/2],[r2,l/2]])
|
||||
else [r1,-l/2],
|
||||
if (is_finite(chamf2r) && !approx(chamf2r,0))
|
||||
each [
|
||||
|
@ -1421,7 +1464,7 @@ function cyl(
|
|||
[r2, l/2] + polar_to_xy(chamf2r,180),
|
||||
]
|
||||
else if (is_finite(round2) && !approx(round2,0))
|
||||
each arc(r=abs(round2), corner=[[r1,-l/2],[r2,l/2],[(round2>0?0:1e6),l/2]])
|
||||
each arc(r=abs(round2), corner=[[r1,-l/2],[r2,l/2],[max(0,r2-2*roundlen2),l/2]])
|
||||
else [r2,l/2],
|
||||
if (texture==undef) [0,l/2],
|
||||
]
|
||||
|
|
26
skin.scad
26
skin.scad
|
@ -1026,6 +1026,8 @@ module rotate_sweep(
|
|||
function _taperfunc(x) =
|
||||
let(higofs = pow(0.05,2)) // Smallest hig scale is the square root of this value
|
||||
sqrt((1-higofs)*x+higofs);
|
||||
function _taperfunc(x) =
|
||||
sqrt(1-(1-x)^2);
|
||||
function _ss_polygon_r(N,theta) =
|
||||
let( alpha = 360/N )
|
||||
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
||||
|
@ -1045,8 +1047,8 @@ function spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, hi
|
|||
sides = segs(max(r1,r2)),
|
||||
dir = sign(twist),
|
||||
ang_step = 360/sides*dir,
|
||||
anglist = [for(ang = [0:ang_step:twist-EPSILON]) ang,
|
||||
twist],
|
||||
orig_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),
|
||||
|
@ -1056,12 +1058,21 @@ function spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, hi
|
|||
assert(higang1 < dir*twist/2,"Higbee1 is more than half the threads")
|
||||
assert(higang2 < dir*twist/2,"Higbee2 is more than half the threads")
|
||||
let(
|
||||
// This complicated sampling scheme is designed to ensure that there is always a facet boundary
|
||||
// at the $fn specified location, regardless of what kind of subsampling occurs for tapers."
|
||||
anglist = [
|
||||
for(a=orig_anglist) if (a*dir<higang1-EPSILON) a,
|
||||
dir*higang1,
|
||||
for(a=orig_anglist) if (a*dir>higang1+EPSILON && (twist-a)*dir>higang2+EPSILON) a,
|
||||
twist-dir*higang2,
|
||||
for(a=orig_anglist) if ((twist-a)*dir<higang2-EPSILON) a
|
||||
],
|
||||
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,
|
||||
(higang1>0 && dir*anglist[i+1]<=higang1) || (higang2>0 && dir*(twist-anglist[i])<=higang2)
|
||||
? ceil((anglist[i+1]-anglist[i])/ang_step*higsample)
|
||||
: 1,
|
||||
endpoint=false),
|
||||
last(anglist)
|
||||
],
|
||||
|
@ -1082,8 +1093,9 @@ function spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, hi
|
|||
) pts
|
||||
],
|
||||
vnf = vnf_vertex_array(
|
||||
points, col_wrap=true, caps=true, reverse=dir>0?true:false,
|
||||
style=higbee1>0 || higbee2>0 ? "quincunx" : "alt"
|
||||
points, col_wrap=true, caps=true, reverse=dir>0,
|
||||
// style=higbee1>0 || higbee2>0 ? "quincunx" : "alt"
|
||||
style="convex"
|
||||
)
|
||||
)
|
||||
reorient(anchor,spin,orient, vnf=vnf, r1=r1, r2=r2, l=h, p=vnf);
|
||||
|
|
226
threading.scad
226
threading.scad
|
@ -33,9 +33,9 @@
|
|||
// internal = If true, make this a mask for making internal threads.
|
||||
// d1 = Bottom outside diameter of threads.
|
||||
// d2 = Top outside 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.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -46,6 +46,8 @@
|
|||
// Examples(Med):
|
||||
// threaded_rod(d=10, l=20, pitch=1.25, left_handed=true, $fa=1, $fs=1);
|
||||
// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1);
|
||||
// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, bevel=true);
|
||||
// rot(90)threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, higbee=true);
|
||||
// Example: Diamond threading where both left-handed and right-handed nuts travel (in the same direction) on the threaded rod:
|
||||
// $slop = 0.075;
|
||||
// d = 3/8*INCH;
|
||||
|
@ -147,13 +149,19 @@ module threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
|
||||
// Examples(Med):
|
||||
// threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, $slop=0.05, $fa=1, $fs=1);
|
||||
// threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, left_handed=true, bevel=true, $slop=0.1, $fa=1, $fs=1);
|
||||
// threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, left_handed=true, bevel=false, $slop=0.1, $fa=1, $fs=1);
|
||||
// threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, $slop=0.1, $fa=1, $fs=1);
|
||||
// threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, bevel2=true, $slop=0.1, $fa=1, $fs=1);
|
||||
// rot(90)threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25,higbee=true, $slop=0.1, $fa=1, $fs=1);
|
||||
function threaded_nut(
|
||||
nutwidth, id, h,
|
||||
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
||||
|
@ -163,7 +171,8 @@ function threaded_nut(
|
|||
module threaded_nut(
|
||||
nutwidth, id, h,
|
||||
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
||||
ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
|
||||
ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
|
||||
higbee, higbee1, higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
dummy1=
|
||||
|
@ -198,7 +207,8 @@ module threaded_nut(
|
|||
left_handed=left_handed,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,
|
||||
ibevel1=ibevel1, ibevel2=ibevel2, ibevel=ibevel,
|
||||
height=height, thickness=thickness, bevang=bevang,
|
||||
height=height, thickness=thickness, bevang=bevang,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor, spin=spin,
|
||||
orient=orient
|
||||
) children();
|
||||
|
@ -258,9 +268,9 @@ module threaded_nut(
|
|||
// internal = If true, make this a mask for making internal threads. Default: false
|
||||
// d1 = Bottom outside diameter of threads.
|
||||
// d2 = Top outside diameter of threads.
|
||||
// higbee = Length to taper thread ends over. Default: 0 (No higbee thread tapering)
|
||||
// higbee1 = Length to taper bottom thread end over.
|
||||
// higbee2 = Length to taper top thread end over.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -270,20 +280,20 @@ module threaded_nut(
|
|||
// trapezoidal_threaded_rod(d=10, l=15, pitch=2, orient=BACK);
|
||||
// Examples(Med):
|
||||
// trapezoidal_threaded_rod(d=10, l=40, pitch=2, $fn=32); // Standard metric threading
|
||||
// trapezoidal_threaded_rod(d=10, l=17, pitch=2, higbee=25, $fn=32); // Standard metric threading
|
||||
// rot(-65)trapezoidal_threaded_rod(d=10, l=17, pitch=2, higbee=25, $fn=32); // Standard metric threading
|
||||
// trapezoidal_threaded_rod(d=10, l=17, pitch=2, bevel=true, $fn=32); // Standard metric threading
|
||||
// trapezoidal_threaded_rod(d=10, l=30, pitch=2, left_handed=true, $fa=1, $fs=1); // Standard metric threading
|
||||
// trapezoidal_threaded_rod(d=10, l=40, pitch=3, left_handed=true, starts=3, $fn=36);
|
||||
// trapezoidal_threaded_rod(l=25, d=10, pitch=2, starts=3, $fa=1, $fs=1, orient=RIGHT, anchor=BOTTOM);
|
||||
// trapezoidal_threaded_rod(l=25, d=10, pitch=2, starts=3, $fa=1, $fs=1, bevel=true, orient=RIGHT, anchor=BOTTOM);
|
||||
// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, $fa=2, $fs=2);
|
||||
// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, starts=4, $fa=2, $fs=2);
|
||||
// trapezoidal_threaded_rod(d=16, l=40, pitch=2, thread_angle=60);
|
||||
// trapezoidal_threaded_rod(d=25, l=40, pitch=10, thread_depth=8/3, thread_angle=100, starts=4, anchor=BOT, $fa=2, $fs=2);
|
||||
// trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=60, starts=11, higbee=10,$fn=120);
|
||||
// trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=60, starts=11, higbee=true,$fn=120);
|
||||
// Example(Med): Using as a Mask to Make Internal Threads
|
||||
// bottom_half() difference() {
|
||||
// cube(50, center=true);
|
||||
// trapezoidal_threaded_rod(d=40, l=51, pitch=5, thread_angle=30, internal=true, orient=RIGHT, $fn=36);
|
||||
// trapezoidal_threaded_rod(d=40, l=51, pitch=5, thread_angle=30, internal=true, bevel=true, orient=RIGHT, $fn=36);
|
||||
// }
|
||||
function trapezoidal_threaded_rod(
|
||||
d, l, pitch,
|
||||
|
@ -354,6 +364,9 @@ module trapezoidal_threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -363,6 +376,7 @@ module trapezoidal_threaded_rod(
|
|||
// trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, bevel=true, $slop=0.05, anchor=UP);
|
||||
// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, $slop=0.1, left_handed=true);
|
||||
// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15);
|
||||
// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15, higbee=true);
|
||||
// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=0, $slop=0.2); // No threads
|
||||
function trapezoidal_threaded_nut(
|
||||
nutwidth,
|
||||
|
@ -377,6 +391,7 @@ function trapezoidal_threaded_nut(
|
|||
ibevel1,ibevel2,ibevel,
|
||||
thickness,height,
|
||||
id1,id2,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) = no_function("trapezoidal_threaded_nut");
|
||||
module trapezoidal_threaded_nut(
|
||||
|
@ -392,6 +407,7 @@ module trapezoidal_threaded_nut(
|
|||
ibevel1,ibevel2,ibevel,
|
||||
thickness,height,
|
||||
id1,id2,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
dummy1 = assert(is_num(pitch) && pitch>=0 && thread_angle>=0 && thread_angle<180);
|
||||
|
@ -410,6 +426,7 @@ module trapezoidal_threaded_nut(
|
|||
generic_threaded_nut(nutwidth=nutwidth,id=id,h=h,pitch=pitch,profile=profile,id1=id1,id2=id2,
|
||||
shape=shape,left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts,
|
||||
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,bevang=bevang,height=height,thickness=thickness,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor,spin=spin,orient=orient)
|
||||
children();
|
||||
}
|
||||
|
@ -433,9 +450,9 @@ module trapezoidal_threaded_nut(
|
|||
// bevel1 = if true bevel the bottom end.
|
||||
// bevel2 = if true bevel the top end.
|
||||
// internal = If true, this is a mask for making internal threads.
|
||||
// higbee = Length to taper thread ends over. Default: 0 (No higbee thread tapering)
|
||||
// higbee1 = Length to taper bottom thread end over.
|
||||
// higbee2 = Length to taper top thread end over.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -474,6 +491,7 @@ module acme_threaded_rod(
|
|||
left_handed=left_handed,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,
|
||||
internal=internal, length=length,
|
||||
higbee=higbee,
|
||||
anchor=anchor,
|
||||
spin=spin,
|
||||
orient=orient
|
||||
|
@ -504,6 +522,9 @@ module acme_threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -511,6 +532,7 @@ module acme_threaded_rod(
|
|||
// Examples(Med):
|
||||
// acme_threaded_nut(nutwidth=16, id=3/8*INCH, h=8, tpi=8, $slop=0.05);
|
||||
// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1);
|
||||
// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1,ibevel=false,higbee=true);
|
||||
function acme_threaded_nut(
|
||||
nutwidth, id, h, tpi, pitch,
|
||||
starts=1,
|
||||
|
@ -518,6 +540,7 @@ function acme_threaded_nut(
|
|||
bevel,bevel1,bevel2,bevang=30,
|
||||
ibevel,ibevel1,ibevel2,
|
||||
height,thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) = no_function("acme_threaded_nut");
|
||||
module acme_threaded_nut(
|
||||
|
@ -527,6 +550,7 @@ module acme_threaded_nut(
|
|||
bevel,bevel1,bevel2,bevang=30,
|
||||
ibevel,ibevel1,ibevel2,
|
||||
height,thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
dummy = assert(num_defined([pitch,tpi])==1,"Must give exactly one of pitch and tpi");
|
||||
|
@ -541,6 +565,7 @@ module acme_threaded_nut(
|
|||
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
|
||||
height=height,thickness=thickness,
|
||||
starts=starts,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor,
|
||||
spin=spin,
|
||||
orient=orient
|
||||
|
@ -606,13 +631,12 @@ module npt_threaded_rod(
|
|||
internal=false,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
checks =
|
||||
assert(is_finite(size))
|
||||
assert(is_bool(left_handed))
|
||||
assert(is_undef(bevel) || is_bool(bevel))
|
||||
assert(is_bool(hollow))
|
||||
assert(is_bool(internal))
|
||||
assert(!(internal&&hollow), "Cannot created a hollow internal threads mask.");
|
||||
assert(is_finite(size));
|
||||
assert(is_bool(left_handed));
|
||||
assert(is_undef(bevel) || is_bool(bevel));
|
||||
assert(is_bool(hollow));
|
||||
assert(is_bool(internal));
|
||||
assert(!(internal&&hollow), "Cannot created a hollow internal threads mask.");
|
||||
info_table = [
|
||||
// Size len OD TPI
|
||||
[ 1/16, [ 0.3896, 0.308, 27 ]],
|
||||
|
@ -660,7 +684,7 @@ module npt_threaded_rod(
|
|||
left_handed=left_handed,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,
|
||||
internal=internal,
|
||||
higbee=r1*PI/2
|
||||
higbee=true
|
||||
);
|
||||
if (hollow) cylinder(l=l+1, d=size*INCH, center=true);
|
||||
}
|
||||
|
@ -690,9 +714,9 @@ module npt_threaded_rod(
|
|||
// bevel1 = if true bevel the bottom end.
|
||||
// bevel2 = if true bevel the top end.
|
||||
// internal = If true, this is a mask for making internal 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.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// d1 = Bottom outside diameter of threads.
|
||||
// d2 = Top outside diameter of threads.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -710,9 +734,7 @@ function buttress_threaded_rod(
|
|||
left_handed=false,
|
||||
bevel,bevel1,bevel2,
|
||||
internal=false,
|
||||
higbee=0,
|
||||
higbee1,
|
||||
higbee2,
|
||||
higbee, higbee1, higbee2,
|
||||
d1,d2,starts=1,length,
|
||||
anchor, spin, orient
|
||||
) = no_function("buttress_threaded_rod");
|
||||
|
@ -721,9 +743,7 @@ module buttress_threaded_rod(
|
|||
left_handed=false,
|
||||
bevel,bevel1,bevel2,
|
||||
internal=false,
|
||||
higbee=0,
|
||||
higbee1,
|
||||
higbee2,
|
||||
higbee,higbee1,higbee2,
|
||||
d1,d2,starts=1,length,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
|
@ -735,6 +755,10 @@ module buttress_threaded_rod(
|
|||
[ 7/16, -0.75],
|
||||
[ 1/ 2, -0.77],
|
||||
];
|
||||
higbee2 = !internal || (!higbee && !higbee2) ? higbee2
|
||||
: let (higval = first_defined([higbee2,higbee]))
|
||||
is_num(higval) ? higval + 270
|
||||
: 270;
|
||||
generic_threaded_rod(
|
||||
d=d, l=l, pitch=pitch,
|
||||
profile=profile,
|
||||
|
@ -774,6 +798,9 @@ module buttress_threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -785,6 +812,7 @@ function buttress_threaded_nut(
|
|||
pitch, shape="hex", left_handed=false,
|
||||
bevel,bevel1,bevel2,bevang=30,starts=1,
|
||||
ibevel,ibevel1,ibevel2,height,thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) = no_function("buttress_threaded_nut");
|
||||
module buttress_threaded_nut(
|
||||
|
@ -792,6 +820,7 @@ module buttress_threaded_nut(
|
|||
pitch, shape="hex", left_handed=false,
|
||||
bevel,bevel1,bevel2,bevang=30,starts=1,
|
||||
ibevel,ibevel1,ibevel2,height,thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
depth = pitch * 3/4;
|
||||
|
@ -802,6 +831,10 @@ module buttress_threaded_nut(
|
|||
[ 7/16, -0.75],
|
||||
[ 1/ 2, -0.77],
|
||||
];
|
||||
higbee2 = !higbee && !higbee2 ? higbee2
|
||||
: let (higval = first_defined([higbee2,higbee]))
|
||||
is_num(higval) ? higval + 270
|
||||
: 270;
|
||||
generic_threaded_nut(
|
||||
nutwidth=nutwidth, id=id, h=h,
|
||||
pitch=pitch,
|
||||
|
@ -810,6 +843,7 @@ module buttress_threaded_nut(
|
|||
left_handed=left_handed,starts=starts,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang,
|
||||
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor, spin=spin, height=height, thickness=thickness,
|
||||
orient=orient
|
||||
) children();
|
||||
|
@ -836,9 +870,9 @@ module buttress_threaded_nut(
|
|||
// bevel1 = if true bevel the bottom end.
|
||||
// bevel2 = if true bevel the top end.
|
||||
// internal = If true, this is a mask for making internal 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.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// d1 = Bottom outside diameter of threads.
|
||||
// d2 = Top outside diameter of threads.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -856,7 +890,7 @@ function square_threaded_rod(
|
|||
bevel,bevel1,bevel2,
|
||||
starts=1,
|
||||
internal=false,
|
||||
higbee=0, higbee1, higbee2,
|
||||
higbee, higbee1, higbee2,
|
||||
d1,d2,
|
||||
anchor, spin, orient
|
||||
) = no_function("square_threaded_rod");
|
||||
|
@ -912,6 +946,9 @@ module square_threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -926,6 +963,7 @@ function square_threaded_nut(
|
|||
ibevel,ibevel1,ibevel2,
|
||||
height,thickness,
|
||||
starts=1,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) = no_function("square_threaded_nut");
|
||||
module square_threaded_nut(
|
||||
|
@ -935,6 +973,7 @@ module square_threaded_nut(
|
|||
bevel,bevel1,bevel2,bevang=30,
|
||||
ibevel,ibevel1,ibevel2,
|
||||
height,thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
starts=1,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
|
@ -947,6 +986,7 @@ module square_threaded_nut(
|
|||
ibevel=ibevel, ibevel1=ibevel1, ibevel2=ibevel2,
|
||||
height=height,thickness=thickness,
|
||||
starts=starts,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
anchor=anchor,
|
||||
spin=spin,
|
||||
orient=orient
|
||||
|
@ -1051,8 +1091,13 @@ module ball_screw_rod(
|
|||
// If bevel is set to true and internal is false then the ends of the rod will be beveled. When bevel is true and internal is true the ends of the rod will
|
||||
// be filled in so that the rod mask will create a bevel when subtracted from an object. The bevel is at 45 deg and is the depth of the threads.
|
||||
// .
|
||||
// Higbee specifies tapering of the thread ends to make screws easier to start. Specify the number of degrees for the taper. Higbee
|
||||
// only works for external threads. It is ignored if internal is true.
|
||||
// Higbee or blunt start threading specifies that the thread ends abruptly at its full width instead of running off the end of the shaft and leaving a sharp edged partial
|
||||
// thread at the end of the screw. This makes screws easier to start and
|
||||
// prevents cross threading. If you set `higbee=true` then the blunt start applies to both ends. The blunt start cuts the thread end in a single facet,
|
||||
// so if you use lots of facets it will be close to perpendicular to the screw surface, but if you use fewer facets, it will be a more sloped cut.
|
||||
// The place to cut the threads is calculated to try to leave a 1/4 thread gap from the end of the screw, but depending on your profile, you may
|
||||
// wish to adjust this. If you set higbee to a numerical value it will be added to the computed higbee angle, so a positive value will cut the thread back farther
|
||||
// giving more space at the end. Higbee works on both internal and external threads.
|
||||
// Arguments:
|
||||
// d = Outer diameter of threaded rod.
|
||||
// l / length = Length of threaded rod.
|
||||
|
@ -1067,9 +1112,9 @@ module ball_screw_rod(
|
|||
// internal = If true, make this a mask for making internal threads. Default: false
|
||||
// d1 = Bottom outside diameter of threads.
|
||||
// d2 = Top outside diameter of threads.
|
||||
// higbee = Angle to taper thread ends over. Default: 0 (No higbee thread tapering)
|
||||
// higbee1 = Angle to taper bottom thread end over.
|
||||
// higbee2 = Angle to taper top thread end over.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// 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`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
|
@ -1121,13 +1166,20 @@ module generic_threaded_rod(
|
|||
anchor, spin, orient
|
||||
) {
|
||||
l = one_defined([l,length],"l,length");
|
||||
dummy0 =
|
||||
assert(all_positive(pitch))
|
||||
assert(all_positive(l))
|
||||
assert(is_path(profile))
|
||||
assert(is_bool(left_handed));
|
||||
bevel1 = first_defined([bevel1,bevel,false]);
|
||||
bevel2 = first_defined([bevel2,bevel,false]);
|
||||
thigbee1 = first_defined([higbee1,higbee,false]);
|
||||
thigbee2 = first_defined([higbee2,higbee,false]);
|
||||
// Zero higbee should be treated as "true", default angle, but it tests as false so adjust
|
||||
higbee1 = thigbee1==0 ? true : thigbee1;
|
||||
higbee2 = thigbee2==0 ? true : thigbee2;
|
||||
dummy0 =
|
||||
assert(all_positive([pitch]),"Thread pitch must be a positive value")
|
||||
assert(all_positive([l]),"Length must be a postive value")
|
||||
assert(is_path(profile),"Profile must be a path")
|
||||
assert(is_finite(higbee1) || is_bool(higbee1), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
|
||||
assert(is_finite(higbee2) || is_bool(higbee2), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
|
||||
assert(is_bool(left_handed));
|
||||
r1 = get_radius(d1=d1, d=d);
|
||||
r2 = get_radius(d1=d2, d=d);
|
||||
sides = quantup(segs(max(r1,r2)), starts);
|
||||
|
@ -1138,10 +1190,19 @@ module generic_threaded_rod(
|
|||
threads = quantup(l/pitch+2,1); // Was quantup(1/pitch+2,2*starts);
|
||||
dir = left_handed? -1 : 1;
|
||||
twist = 360 * l / pitch / starts;
|
||||
higang1 = first_defined([higbee1, higbee, 0]);
|
||||
higang2 = first_defined([higbee2, higbee, 0]);
|
||||
assert(higang1 < twist/2);
|
||||
assert(higang2 < twist/2);
|
||||
profile = !internal ? profile
|
||||
: [
|
||||
for(entry=profile) if (entry.x>=0) [entry.x-1/2,entry.y],
|
||||
for(entry=profile) if (entry.x<0) [entry.x+1/2,entry.y]
|
||||
];
|
||||
gap = 0.25;
|
||||
thread_minx = min(column(profile,0));
|
||||
thread_maxx = max(column(profile,0));
|
||||
// Compute higbee cut angles, or set to large negative value if higbee is not enabled
|
||||
higang1 = !higbee1 ? -1000
|
||||
: (180+(gap-(thread_minx+.5))*360)/starts + (is_num(higbee1) ? higbee1 : 0);
|
||||
higang2 = !higbee2 ? -1000
|
||||
: (180+(gap-(.5-thread_maxx))*360)/starts + (is_num(higbee2) ? higbee2 : 0);
|
||||
prof3d = path3d(profile);
|
||||
pdepth = -min(column(profile,1));
|
||||
pmax = pitch * max(column(profile,1));
|
||||
|
@ -1152,12 +1213,6 @@ module generic_threaded_rod(
|
|||
* affine3d_skew(sxz=(_r2-_r1)/l) // Skew correction for tapered threads
|
||||
* frame_map(x=[0,0,1], y=[1,0,0]) // Map profile to 3d, parallel to z axis
|
||||
* scale(pitch); // scale profile by pitch
|
||||
hig_table = [
|
||||
[-twist/2-0.0001, 0],
|
||||
[-twist/2+higang1, 1],
|
||||
[ twist/2-higang2, 1],
|
||||
[ twist/2+0.0001, 0],
|
||||
];
|
||||
start_steps = sides / starts;
|
||||
thread_verts = [
|
||||
// Outer loop constructs a vertical column of the screw at each angle
|
||||
|
@ -1169,15 +1224,13 @@ module generic_threaded_rod(
|
|||
full_profile = [ // profile for the entire rod
|
||||
for (thread = [-threads/2:1:threads/2-1]) let(
|
||||
tang = (thread/starts) * 360 + ang,
|
||||
hsc = internal? 1
|
||||
: (higang1==0 && tang<=0)? 1
|
||||
: (higang2==0 && tang>=0)? 1
|
||||
: lookup(tang, hig_table),
|
||||
higscale = yscale(hsc,cp = -pdepth) // Scale for higbee
|
||||
adjusted_prof3d = tang < -twist/2+higang1 || tang > twist/2-higang2
|
||||
? [for(v=prof3d) [v.x,internal?pmax/pitch:-pdepth,v.z]]
|
||||
: prof3d
|
||||
)
|
||||
// The right movement finds the position of the thread along
|
||||
// what will be the z axis after the profile is mapped to 3d
|
||||
each apply(right(dz + thread) * higscale, prof3d)
|
||||
each apply(right(dz + thread) , adjusted_prof3d)
|
||||
]
|
||||
) [
|
||||
[0, 0, -l/2-pitch],
|
||||
|
@ -1185,8 +1238,7 @@ module generic_threaded_rod(
|
|||
[0, 0, +l/2+pitch]
|
||||
]
|
||||
];
|
||||
|
||||
style = higang1>0 || higang2>0 ? "quincunx" : "min_edge";
|
||||
style=internal?"concave":"convex";
|
||||
|
||||
thread_vnfs = vnf_join([
|
||||
// Main thread faces
|
||||
|
@ -1239,11 +1291,13 @@ module generic_threaded_rod(
|
|||
up(l/2) cuboid([2*rmax+1,2*rmax+1, maxlen], anchor=BOTTOM);
|
||||
}
|
||||
|
||||
/* intersection(){
|
||||
/* // slower, simpler approach for beveling
|
||||
intersection(){
|
||||
//vnf_validate(vnf_quantize(thread_vnfs), size=0.1);
|
||||
vnf_polyhedron(vnf_quantize(thread_vnfs), convexity=10);
|
||||
cyl(l=l, r1=_r1+pmax, r2=_r2+pmax, chamfer1=bevel1?depth:undef, chamfer2=bevel2?depth:undef);
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
|
||||
// Add bevel for internal thread mask
|
||||
if (internal) {
|
||||
|
@ -1282,6 +1336,9 @@ module generic_threaded_rod(
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// id1 = inner diameter at the bottom
|
||||
// id2 = inner diameter at the top
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -1300,6 +1357,7 @@ function generic_threaded_nut(
|
|||
bevel,bevel1,bevel2,bevang=30,
|
||||
ibevel, ibevel1, ibevel2,
|
||||
id1,id2, height, thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) = no_function("generic_threaded_nut");
|
||||
module generic_threaded_nut(
|
||||
|
@ -1314,6 +1372,7 @@ module generic_threaded_nut(
|
|||
bevel,bevel1,bevel2,bevang=30,
|
||||
ibevel, ibevel1, ibevel2,
|
||||
id1,id2, height, thickness,
|
||||
higbee,higbee1,higbee2,
|
||||
anchor, spin, orient
|
||||
) {
|
||||
|
||||
|
@ -1349,7 +1408,8 @@ module generic_threaded_nut(
|
|||
left_handed=left_handed,
|
||||
starts=starts,
|
||||
internal=true,
|
||||
bevel1=ibevel1,bevel2=ibevel2
|
||||
bevel1=ibevel1,bevel2=ibevel2,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2
|
||||
);
|
||||
}
|
||||
children();
|
||||
|
@ -1369,7 +1429,7 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
|
|||
fn = quantup(segs(r=nutwidth/2),shape=="hex"?6:4);
|
||||
d = shape=="hex" ? 2*nutwidth/sqrt(3) : sqrt(2)*nutwidth;
|
||||
chamfsize = (d-nutwidth)/2/bevel_d;
|
||||
cyl(d=d*.99,h=h+.01,realign=true,circum=true,$fn=fn,chamfer1=bevel1?chamfsize:0,chamfer2=bevel2?chamfsize:0,chamfang=90-30);
|
||||
cyl(d=d*.99,h=h+.01,realign=true,circum=true,$fn=fn,chamfer1=bevel1?chamfsize:0,chamfer2=bevel2?chamfsize:0,chamfang=30);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1378,19 +1438,23 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
|
|||
// Usage:
|
||||
// thread_helix(d, pitch, [thread_depth], [flank_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]);
|
||||
// Description:
|
||||
// Creates a right-handed helical thread with optional end tapering. Unlike generic_threaded_rod, this module just generates the thread, and
|
||||
// you specify the angle of thread you want, which makes it easy to put complete threads onto a longer shaft. It also makes a more finely
|
||||
// divided taper at the thread ends. However, it takes about twice as long to render compared to generic_threaded_rod.
|
||||
|
||||
// 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
|
||||
// angle of threading that you want, which makes it easy to put complete threads onto a longer
|
||||
// shaft. It also optionally makes a finely divided taper at the thread ends. However, it takes
|
||||
// 2-3 times as long to render compared to {{generic_threaded_rod()}}. This module was designed
|
||||
// to handle threads found in plastic and glass bottles.
|
||||
// .
|
||||
// You can specify a thread_depth and flank_angle, in which
|
||||
// case you get a symmetric trapezoidal thread, whose inner diameter (the base of the threads for external threading)
|
||||
// is d (so the total diameter will be d + thread_depth). This differs from the threaded_rod modules, where the specified
|
||||
// diameter is the outer diameter.
|
||||
// Alternatively 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.
|
||||
// You can specify a thread_depth and flank_angle, in which case you get a symmetric trapezoidal
|
||||
// thread, whose inner diameter (the base of the threads for external threading) is d (so the
|
||||
// total diameter will be d + thread_depth). This differs from the threaded_rod modules, where
|
||||
// the specified diameter is the outer diameter. Alternatively 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.
|
||||
// .
|
||||
// Unlike generic_threaded_rod, when internal=true this module generates the threads, not a thread mask.
|
||||
// Unlike {{generic_threaded_rod()}, when internal=true this module generates the threads, not a thread mask.
|
||||
// The profile needs to be inverted to produce the proper thread form. If you use the built-in trapezoidal
|
||||
// thread you get the inverted thread, designed so that the inner diameter is d. If you supply a custom profile
|
||||
// you must invert it yourself to get internal threads. With adequate clearance
|
||||
|
@ -1398,7 +1462,7 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
|
|||
// unlike the threaded_rod modules, thread_helix does not adjust the diameter for faceting, nor does it
|
||||
// subtract any $slop for clearance.
|
||||
// .
|
||||
// Higbee specifies tapering applied to the ends of the threads and is given as the linear distance
|
||||
// The taper options specify Higbee specifies tapering applied to the ends of the threads and is given as the linear distance
|
||||
// over which to taper. Tapering works on both internal and external threads.
|
||||
// Arguments:
|
||||
// d = Inside base diameter of threads. Default: 10
|
||||
|
|
|
@ -508,11 +508,11 @@ direction you can use anchor arrows.
|
|||
## Anchor Directions and Anchor Arrows
|
||||
For the ant on the sphere it is obvious which direction is UP; that
|
||||
direction corresponds to the Z+ axis. The location of the X and Y
|
||||
axes is less clear and in fact it may be arbitrary.
|
||||
One way that is useful to show the position and orientation of an anchor point is by attaching
|
||||
an anchor arrow to that anchor. As noted before, the small red flag
|
||||
points in the direction of the anchor's Y+ axis when the spin is
|
||||
zero.
|
||||
axes is less clear and in fact it may be arbitrary. One way that is
|
||||
useful to show the position and orientation of an anchor point is by
|
||||
attaching an anchor arrow to that anchor. As noted before, the small
|
||||
red flag points in the direction of the anchor's Y+ axis when the spin
|
||||
is zero.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
|
@ -565,7 +565,7 @@ module with a single argument, which specifies the anchor on the parent
|
|||
where the child will attach. This will attach the bottom of the child
|
||||
to the given anchor point on the parent. The child appears on the parent with its
|
||||
Z direction aligned parallel to the parent's anchor direction, and
|
||||
it's Y direction spin to point in the zero spin direction for the
|
||||
its Y direction pointing in the zero spin direction for the
|
||||
parent anchor. The anchor direction of the child does not affect the result in this
|
||||
case.
|
||||
|
||||
|
@ -581,7 +581,7 @@ cube(50,center=true)
|
|||
attach(RIGHT+TOP)cylinder(d1=30,d2=15,l=25);
|
||||
```
|
||||
|
||||
In the second example, the child object point diagonally away
|
||||
In the second example, the child object points diagonally away
|
||||
from the cube. If you want the child at at edge of the parent it's
|
||||
likely that this result will not be what you want. To get a different
|
||||
result, use `position()` with `orient(anchor=)`, if needed.
|
||||
|
@ -600,7 +600,7 @@ In the above example we anchor the child to its FRONT and then attach
|
|||
it to the RIGHT. An ambiguity exists regarding the spin of the
|
||||
parent's coordinate system. How is this resolved? The small flags
|
||||
on the anchor arrows show the position of zero spin by pointing
|
||||
towards the local Y direction. For the above
|
||||
towards the local Y+ direction, which is also the BACK direction of the child. For the above
|
||||
cube, the arrow looks like this:
|
||||
|
||||
```openscad-3D
|
||||
|
@ -649,8 +649,8 @@ cube(50,center=true)
|
|||
```
|
||||
|
||||
On the other hand, if you put the translation between the attach and
|
||||
the object in your code, then it will act in the coordinate system of
|
||||
the parent, so in the example below it moves to the right.
|
||||
the object in your code, then it will act in the local coordinate system of
|
||||
the parent at the parent's anchor, so in the example below it moves to the right.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// LibFile: vectors.scad
|
||||
// This file provides some mathematical operations that apply to each
|
||||
// entry in a vector. It provides normalizatoin and angle computation, and
|
||||
// entry in a vector. It provides normalization and angle computation, and
|
||||
// it provides functions for searching lists of vectors for matches to
|
||||
// a given vector.
|
||||
// Includes:
|
||||
|
|
Loading…
Reference in a new issue