diff --git a/joiners.scad b/joiners.scad index 45ff5bf..a815e25 100644 --- a/joiners.scad +++ b/joiners.scad @@ -1247,54 +1247,72 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1 // to remove. The teeth valleys are chamfered by half the specified value to ensure that there is room for the parts // to mate. The base is added based on the unchamfered dimensions of the joint, and the "teeth_bot" anchor is located // based on the unchamfered dimensions. +// . +// By default the teeth are symmetric, which is ideal for registration and for situations where loading may occur in either +// direction. The skew parameter will skew the teeth by the specified amount, where a skew of ±1 gives a tooth with a vertical +// side either on the left or the right. Intermediate values will produce partially skewed teeth. Note that the skew +// applies after the tooth profile is computed with the specified tooth_angle, which means that the skewed tooth will +// have an altered tooth angle from the one specified. +// . +// 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`. + // Named Anchors: -// "teeth_bot" = center of the joint, aligned with the bottom of the (unchamfered) teeth, pointing DOWN. -// "mate" = center of the joint, pointing UP, but with the correct spin so that the part will mate with a compatible parent joint. +// "teeth_bot" = center of the joint, aligned with the bottom of the (unchamfered/unrounded) teeth, pointing DOWN. // Arguments: // n = number of teeth // ir/id = inner radius or diameter // or/od = outer radius or diameter // tooth_angle = nominal tooth angle. Default: 60 // cone_angle = raise or lower the angle of the teeth in the radial direction. Default: 0 +// skew = skew the tooth shape. Default: 0 // chamfer = chamfer teeth by this fraction at tips and half this fraction at valleys. Default: 0 -// roudning = round the teeth by this fraction at the tips, and half this fraction at valleys. Default: 0 +// rounding = round the teeth by this fraction at the tips, and half this fraction at valleys. Default: 0 +// rot = if true rotate so the part will mate (via attachment) with another identical part. Default: false // base = add base of this height to the bottom. Default: 1 // crop = crop to a cylindrical shape. 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` -// Example: Basic uncropped hirth spline +// Example(3D,NoScale): Basic uncropped hirth spline // hirth(32,20,50); -// Example: Raise cone angle +// Example(3D,NoScale): Raise cone angle // hirth(32,20,50,cone_angle=30); -// Example: Lower cone angle +// Example(3D,NoScale): Lower cone angle // hirth(32,20,50,cone_angle=-30); -// Example: Adding a large base +// Example(3D,NoScale): Adding a large base // hirth(20,20,50,base=20); -// Example: Only 8 teeth, with chamfering +// Example(3D,NoScale): Only 8 teeth, with chamfering // hirth(8,20,50,tooth_angle=60,base=10,chamfer=.1); -// Example: Only 8 teeth, cropped +// Example(3D,NoScale): Only 8 teeth, cropped // hirth(8,20,50,tooth_angle=60,base=10,chamfer=.1, crop=true); -// Example: Only 8 teeth, with rounding +// Example(3D,NoScale): Only 8 teeth, with rounding // hirth(8,20,50,tooth_angle=60,base=10,rounding=.1); -// Example: Only 8 teeth, different tooth angle, cropping with $fn to crop cylinder aligned with teeth +// Example(3D,NoScale): Only 8 teeth, different tooth angle, cropping with $fn to crop cylinder aligned with teeth // hirth(8,20,50,tooth_angle=90,base=10,rounding=.05,crop=true,$fn=48); -// Example: Two identical parts joined together (with 1 unit offset to reveal the joint line). With odd tooth count you can use the CENTER anchor for the child and the teeth line up correctly. +// Example(3D,NoScale): Two identical parts joined together (with 1 unit offset to reveal the joint line). With odd tooth count and no skew the teeth line up correctly: // hirth(27,20,50, tooth_angle=60,base=2,chamfer=.05) // up(1) attach(CENTER,CENTER) // hirth(27,20,50, tooth_angle=60,base=2,chamfer=.05); -// Example: Two conical parts joined together, with opposite cone angles for a correct joint. With an even tooth count you must use the "mate" anchor for correct alignment of the teeth. +// Example(3D,NoScale): Two conical parts joined together, with opposite cone angles for a correct joint. With an even tooth count one part needs to be rotated for the parts to align: // hirth(26,20,50, tooth_angle=60,base=2,cone_angle=30,chamfer=.05) -// up(1) attach(CENTER,"mate") -// hirth(26,20,50, tooth_angle=60,base=2,cone_angle=-30, chamfer=.05); +// up(1) attach(CENTER,CENTER) +// hirth(26,20,50, tooth_angle=60,base=2,cone_angle=-30, chamfer=.05, rot=true); +// Example(3D,NoScale): Using skew to create teeth with vertical faces +// hirth(17,20,50,skew=-1, base=5, chamfer=0.05); +// Example(3D,NoScale): If you want to change how tall the teeth are you do that by chaging the tooth angle. Increasing the tooth angle makes the teeth shorter: +// hirth(17,20,50,tooth_angle=120,skew=0, base=5, rounding=0.05, crop=true); -module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, rounding, base=1, crop=false, orient,anchor,spin) +module hirth(n, ir, or, id, od, tooth_angle=60, cone_angle=0, chamfer, rounding, base=1, crop=false,skew=0, rot=false, orient,anchor,spin) { ir = get_radius(r=ir,d=id); or = get_radius(r=or,d=od); dummy = assert(all_positive([ir]), "ir/id must be a positive value") assert(all_positive([or]), "or/od must be a positive value") assert(is_int(n) && n>1, "n must be an integer larger than 1") + assert(is_finite(skew) && abs(skew)<=1, "skew must be a number between -1 and 1") assert(ir