mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Merge pull request #1507 from adrianVmariano/master
Will hirth fixes never cease?
This commit is contained in:
commit
ab2d381034
2 changed files with 34 additions and 4 deletions
36
joiners.scad
36
joiners.scad
|
@ -1262,7 +1262,14 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
|||
// The joint is constructed with a tooth peak aligned with the X+ axis.
|
||||
// For two hirth joints to mate they must have the same tooth count, opposite cone angles, and the chamfer/rounding values
|
||||
// must be equal. (One can be chamfered and one rounded, but with the same value.) The rotation required to mate the parts
|
||||
// depends on the skew and whether the tooth count is odd or even. To apply this rotation automatically, set `rot=true`.
|
||||
// depends on the skew and whether the tooth count is odd or even. To apply this rotation automatically, set `rot=true`.
|
||||
// .
|
||||
// When you pick extreme parameters such as very large cone angle, or very small tooth count (e.g. 2 or 3), the joint may
|
||||
// develop a weird shape, and the shape may be unexpectedly sensitive to things like whether chamfering is enabled. It is difficult
|
||||
// to identify the point where the shapes become odd, or even perhaps invalid. For example, with 2 teeth a skew of 0.95 works fine, but
|
||||
// a skew of 0.97 produces a truncated shape and 0.99 produces a 2-part shape. A skew of 1 produces a degenerate, invalid shape.
|
||||
// Since it's hard to determine which parameters, exactly, produce "bad" outcomes, we have chosen not to limit the production
|
||||
// of the extreme shapes, so take care if using extreme parameter values.
|
||||
// Named Anchors:
|
||||
// "teeth_bot" = center of the joint, aligned with the bottom of the (unchamfered/unrounded) teeth, pointing DOWN.
|
||||
// Arguments:
|
||||
|
@ -1351,7 +1358,7 @@ module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, rounding,
|
|||
];
|
||||
full = deduplicate(concat(basicprof, reverse(xflip(basicprof))));
|
||||
skewed = back(valley_angle, skew(sxy=skew*angle/(ridge_angle-valley_angle),fwd(valley_angle,full)));
|
||||
profile = is_undef(rounding) ? skewed
|
||||
pprofile = is_undef(rounding) ? skewed
|
||||
:
|
||||
let(
|
||||
segs = max(16,segs(or*rounding)),
|
||||
|
@ -1360,20 +1367,43 @@ module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, rounding,
|
|||
roundpts = round_corners(skewed, joint=joints, closed=false,$fn=segs)
|
||||
)
|
||||
roundpts;
|
||||
profile = [
|
||||
for(i=[0:1:len(pprofile)-2]) each [pprofile[i],
|
||||
if (pprofile[i+1].x-pprofile[i].x > 90) // Interpolate an extra point if angle > 90 deg
|
||||
let(
|
||||
edge = cyl_proj(or, select(pprofile,i,i+1)),
|
||||
cutpt = xyz_to_spherical(lerp(edge[0],edge[1],.48)) // Exactly .5 is too close to or crosses the origin
|
||||
)
|
||||
[cutpt.y,90-cutpt.z]
|
||||
],
|
||||
last(pprofile)
|
||||
];
|
||||
|
||||
// This code computes the realized tooth angle
|
||||
// out = cyl_proj(or, pprofile);
|
||||
// in = cyl_proj(ir,pprofile);
|
||||
// p1 = plane3pt(out[0], out[1], in[1]);
|
||||
// p2 = plane3pt(out[2], out[1], in[1]);
|
||||
// echo(toothang=vector_angle(plane_normal(p1), plane_normal(p2)));
|
||||
|
||||
bottom = min([tan(valley_angle)*ir,tan(valley_angle)*or])-base-cone_height*ir;
|
||||
safebottom = min([tan(valley_angle)*ir/factor,tan(valley_angle)*or*factor])-base-(crop?1:0)-cone_height*ir;
|
||||
ang_ofs = !rot ? -skew*angle
|
||||
: n%2==0 ? -(angle-skew*angle) - skew*angle
|
||||
: -angle*(2-skew)-skew*angle;
|
||||
|
||||
topinner = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false))
|
||||
each zrot(ang+ang_ofs,cyl_proj(ir/factor,profile))]);
|
||||
topouter = down(cone_height*ir,[for(ang=lerpn(0,360,n,endpoint=false))
|
||||
each zrot(ang+ang_ofs,cyl_proj(factor*or,profile))]);
|
||||
|
||||
safebottom = min(min(column(topinner,2)), min(column(topouter,2))) - base - (crop?1:0);
|
||||
|
||||
botinner = [for(val=topinner) [val.x,val.y,safebottom]];
|
||||
botouter = [for(val=topouter) [val.x,val.y,safebottom]];
|
||||
vert = [topouter, topinner, botinner, botouter];
|
||||
|
||||
datamin = min(min(column(topinner,2)), min(column(topouter,2)));
|
||||
|
||||
anchors = [
|
||||
named_anchor("teeth_bot", [0,0,bottom], DOWN)
|
||||
];
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
// is_vector([],zero=false); // Returns false
|
||||
function is_vector(v, length, zero, all_nonzero=false, eps=EPSILON) =
|
||||
is_list(v) && len(v)>0 && []==[for(vi=v) if(!is_finite(vi)) 0]
|
||||
&& (is_undef(length) || len(v)==length)
|
||||
&& (is_undef(length) || (assert(is_num(length))len(v)==length))
|
||||
&& (is_undef(zero) || ((norm(v) >= eps) == !zero))
|
||||
&& (!all_nonzero || all_nonzero(v)) ;
|
||||
|
||||
|
|
Loading…
Reference in a new issue