diff --git a/readme.md b/readme.md index de48258..1367a27 100644 --- a/readme.md +++ b/readme.md @@ -5229,6 +5229,7 @@ Rounded fillet for adding to corners. Utilities for making involute gears. Formulas from + and ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D. @@ -5241,6 +5242,8 @@ The clearance between tip and root defaults to module / 6, but can be overridden The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum. +```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms. + [utils/gears.scad](utils/gears.scad) Implementation. @@ -5249,8 +5252,10 @@ The origin of the rack is the left end of the pitch line and its width is below ### Functions | Function | Description | |:--- |:--- | -| ```centre_distance(m, z1, z2, pa)``` | Calculate distance between centres taking profile shift into account | +| ```centre_distance(m, z1, z2, pa = 20)``` | Calculate distance between centres taking profile shift into account | | ```involute(r, u)``` | Involute of circle radius r at angle u in radians | +| ```involute_rack_tooth_profile(m, pa = 20, clearance = undef)``` | Calculate rack tooth profile given module and pressure angle | +| ```involute_worm_profile(m, pa = 20, clearance = undef)``` | Calculate worm profile suitable for passing to thread() | | ```profile_shift(z, pa)``` | Calculate profile shift for small gears | ### Modules diff --git a/utils/gears.scad b/utils/gears.scad index 479c7c3..0999b03 100644 --- a/utils/gears.scad +++ b/utils/gears.scad @@ -21,6 +21,7 @@ //! Utilities for making involute gears. //! //! Formulas from +//! //! and //! //! ```involute_gear_profile()``` returns a polygon that can have the bore and spokes, etc, subtracted from it before linear extruding it to 3D. @@ -32,6 +33,8 @@ //! The clearance between tip and root defaults to module / 6, but can be overridden by setting the ```clearance``` parameter. //! //! The origin of the rack is the left end of the pitch line and its width is below the pitch line. I.e. it does not include the addendum. +//! +//! ```involute_worm_profile()``` returns a tooth profile that can be passed to ```thread()``` to make worms. // include use @@ -40,7 +43,7 @@ function involute(r, u) = let(a = degrees(u), c = cos(a), s = sin(a)) r * [c + u function profile_shift(z, pa) = z ? max(1 - z * sqr(sin(pa)) / 2, 0) : 0; //! Calculate profile shift for small gears -function centre_distance(m, z1, z2, pa) = //! Calculate distance between centres taking profile shift into account +function centre_distance(m, z1, z2, pa = 20) = //! Calculate distance between centres taking profile shift into account let(x1 = profile_shift(z1, pa), x2 = profile_shift(z2, pa)) m * (z1/2 + z2/2 + x1 + x2); module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! Calculate gear profile given module, number of teeth and pressure angle @@ -62,7 +65,7 @@ module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! base_r = base_d / 2; p1 = involute(base_r, 0); p2 = involute(base_r, umax); - dist = norm(p2 - p1); // distance between beginning and end of the involute curve + dist = norm(p2 - p1); // distance between beginning and end of the involute curve base_angle = 2 * acos((sqr(base_r) + sqr(tip_d / 2) - sqr(dist)) / base_r / tip_d) + degrees(2 * ta); root_angle = 360 / z - base_angle; @@ -97,35 +100,36 @@ module involute_gear_profile(m, z, pa = 20, clearance = undef, steps = 20) { //! } } +function involute_rack_tooth_profile(m, pa = 20, clearance = undef) = //! Calculate rack tooth profile given module and pressure angle + let(p = PI * m, // Pitch + ha = m, // Addendum + c = is_undef(clearance) ? m / 4 : clearance, // Tip root clearance + hf = m + c, // Dedendum + hw = 2 * m, // Working depth + h = ha + hf, // Tooth depth + crest_w = p / 2 - 2 * ha * tan(pa), // Crest width + base_w = crest_w + 2 * hw * tan(pa), // Base width + root_w = p - base_w, // Root width + clearance_w = root_w - 2 * c * tan(pa), // Width of clearance without fillet + kx = tan(pa / 2 + 45), // Fillet ratio of radius and xoffset + pf = min(0.38 * m, kx * clearance_w / 2), // Dedendum fillet radius + x = pf / kx, // Fillet centre x offset from corner + sides = ceil(r2sides(pf) * (90 - pa) / 360), // Fillet facets taking $fa, $fs and $fn into account + fillet = [ for(i = [0 : sides - 1], a = i * (90 - pa) / sides + 270) [clearance_w / 2 - x, -hf + pf] + pf * [cos(a), sin(a)] ], + reflection = reverse([for(pt = fillet) [p - pt.x, pt.y] ]) // reflect for trailing edge + ) concat(fillet, [ [root_w / 2, -hw / 2], [p / 2 - crest_w / 2, ha], [p / 2 + crest_w / 2, ha], [p - root_w / 2, -hw / 2] ], reflection); + module involute_rack_profile(m, z, w, pa = 20, clearance = undef) { //! Calculate rack profile given module, number of teeth and pressure angle p = PI * m; // Pitch - ha = m; // Addendum hf = 1.25 * m; // Dedendum - hw = 2 * m; // Working depth - h = ha + hf; // Tooth depth - c = is_undef(clearance) ? m / 4 : clearance; // Tip root clearance - crest_w = p / 2 - 2 * ha * tan(pa); // Crest width - base_w = crest_w + 2 * hw * tan(pa); // Base width - root_w = p - base_w; // Root width - clearance_w = root_w - 2 * c * tan(pa); // Width of clearance without fillet - kx = tan(pa / 2 + 45); // Fillet ratio of radius and xoffset - pf = min(0.38 * m, kx * clearance_w / 2); // Dedendum fillet radius - x = pf / kx; // Fillet centre x offset from corner - - tooth = [ [root_w / 2, -hw / 2], [p / 2 - crest_w / 2, ha], [p / 2 + crest_w / 2, ha], [p - root_w / 2, -hw / 2] ]; + tooth = involute_rack_tooth_profile(m, pa, clearance); teeth = [for(i = [0 : z - 1], pt = tooth) [pt.x + i * p, pt.y] ]; - difference() { - polygon(concat([[0, -w], [0, -hf]], teeth, [[z * p, -hf ], [z * p, -w]])); // Add the corners - - for(i = [0 : z]) // Add fillets - hull() { - for(side = [-1, 1]) - translate([i * p + side * (clearance_w / 2 - x), -hf + pf]) - circle(pf); - - translate([i * p, -hw /2 + eps / 2]) // Need to extend to fillet up to meet the root at high pressure angles - square([root_w, eps], center = true); - } - } + polygon(concat([[0, -w], [0, -hf]], teeth, [[z * p, -hf ], [z * p, -w]])); // Add the corners } + +function involute_worm_profile(m, pa = 20, clearance = undef) = //! Calculate worm profile suitable for passing to thread() + let(tooth = involute_rack_tooth_profile(m), + pitch = PI * m, + y_min = min([for(p = tooth) p.y]) + ) [for(p = tooth) [p.x - pitch / 2, p.y - y_min, 0]]; // Offset to be positive in y, centred in x and add 0 z ordintate