Merge pull request #1209 from BelfrySCAD/revarbat_dev

Fixes for gear tooth profiles.
This commit is contained in:
Revar Desmera 2023-07-21 01:34:11 -07:00 committed by GitHub
commit dbcc231336
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1603,6 +1603,7 @@ function worm(
diam_pitch, diam_pitch,
mod, mod,
pitch, pitch,
gear_spin=0,
anchor=CENTER, anchor=CENTER,
spin=0, spin=0,
orient=UP orient=UP
@ -1620,7 +1621,7 @@ function worm(
assert(is_finite(backlash) && backlash>=0) assert(is_finite(backlash) && backlash>=0)
assert(is_bool(left_handed)) assert(is_bool(left_handed))
assert(is_finite(profile_shift) && abs(profile_shift)<1) assert(is_finite(profile_shift) && abs(profile_shift)<1)
//assert(is_finite(gear_spin)) assert(is_finite(gear_spin))
let( let(
helical = asin(starts * circ_pitch / PI / d), helical = asin(starts * circ_pitch / PI / d),
trans_pitch = circ_pitch / cos(helical), trans_pitch = circ_pitch / cos(helical),
@ -1641,7 +1642,7 @@ function worm(
], ],
steps = max(36, segs(d/2)), steps = max(36, segs(d/2)),
step = 360 / steps, step = 360 / steps,
zsteps = ceil(l / circ_pitch * cos(helical) / starts * steps), zsteps = ceil(l / trans_pitch / starts * steps),
zstep = l / zsteps, zstep = l / zsteps,
profiles = [ profiles = [
for (j = [0:1:zsteps]) [ for (j = [0:1:zsteps]) [
@ -1649,14 +1650,18 @@ function worm(
u = i / steps - 0.5, u = i / steps - 0.5,
ang = 360 * (1 - u) + 90, ang = 360 * (1 - u) + 90,
z = j*zstep - l/2, z = j*zstep - l/2,
zoff = circ_pitch * starts * u / cos(helical), zoff = trans_pitch * starts * u,
h = lookup(z+zoff, rack_profile) h = lookup(z+zoff, rack_profile)
) )
cylindrical_to_xyz(d/2+h, ang, z) cylindrical_to_xyz(d/2+h, ang, z)
] ]
], ],
vnf1 = vnf_vertex_array(profiles, caps=true, col_wrap=true, style="alt"), vnf1 = vnf_vertex_array(profiles, caps=true, col_wrap=true, style="alt"),
vnf = left_handed? xflip(p=vnf1) : vnf1 m = product([
zrot(gear_spin),
if (left_handed) xflip(),
]),
vnf = apply(m, vnf1)
) reorient(anchor,spin,orient, d=d, l=l, p=vnf); ) reorient(anchor,spin,orient, d=d, l=l, p=vnf);
@ -1690,6 +1695,8 @@ module worm(
assert(is_bool(left_handed)) assert(is_bool(left_handed))
assert(is_finite(gear_spin)) assert(is_finite(gear_spin))
assert(is_finite(profile_shift) && abs(profile_shift)<1); assert(is_finite(profile_shift) && abs(profile_shift)<1);
helical = asin(starts * circ_pitch / PI / d);
trans_pitch = circ_pitch / cos(helical);
vnf = worm( vnf = worm(
circ_pitch=circ_pitch, circ_pitch=circ_pitch,
starts=starts, starts=starts,
@ -1702,7 +1709,7 @@ module worm(
mod=mod mod=mod
); );
attachable(anchor,spin,orient, d=d, l=l) { attachable(anchor,spin,orient, d=d, l=l) {
zrot(gear_spin) vnf_polyhedron(vnf, convexity=ceil(l/circ_pitch)*2); zrot(gear_spin) vnf_polyhedron(vnf, convexity=ceil(l/trans_pitch)*2);
children(); children();
} }
} }
@ -1850,7 +1857,7 @@ function worm_gear(
left(hob_rad) * left(hob_rad) *
zrot(-90) * zrot(-90) *
back(tbot) * back(tbot) *
scale(cos(u*worm_arc)) * scale(pow(cos(u*worm_arc),2)) *
fwd(tbot), fwd(tbot),
path3d(tooth_profile) path3d(tooth_profile)
) )
@ -2002,6 +2009,9 @@ function _gear_tooth_profile(
helical = 0, helical = 0,
internal = false, internal = false,
profile_shift = 0.0, profile_shift = 0.0,
mod,
diam_pitch,
pitch,
center = false center = false
) = let( ) = let(
// Calculate a point on the involute curve, by angle. // Calculate a point on the involute curve, by angle.
@ -2009,6 +2019,7 @@ function _gear_tooth_profile(
let(b=a*PI/180) base_r * [cos(a)+b*sin(a), sin(a)-b*cos(a)], let(b=a*PI/180) base_r * [cos(a)+b*sin(a), sin(a)-b*cos(a)],
steps = 16, steps = 16,
circ_pitch = circular_pitch(pitch=pitch, circ_pitch=circ_pitch, diam_pitch=diam_pitch, mod=mod),
// Calculate the important circle radii // Calculate the important circle radii
arad = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=internal), arad = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=internal),
@ -2072,8 +2083,8 @@ function _gear_tooth_profile(
// The u values to use when generating the tooth. // The u values to use when generating the tooth.
us = [ us = [
for (i=[0:1:20-1]) 0.2*sin(i/20*90), for (i=[0.0:0.02:0.2-EPSILON]) i,
for (i=[2:1:steps-1]) i/(steps-1), for (i=[0:1:steps-1]) 0.2 + i/(steps-1)*0.8,
], ],
// Generate the left half of the tooth. // Generate the left half of the tooth.
@ -2089,26 +2100,23 @@ function _gear_tooth_profile(
) polar_to_xy(ma_rad, a), ) polar_to_xy(ma_rad, a),
]), ]),
// Find undercut bottom "jaggie" if it exists.
minima = [
for (i = idx(tooth_half_raw))
let(p = tooth_half_raw[i])
if (i > 0 && i < len(tooth_half_raw)-1 && norm(p) <= prad)
let(
pp = tooth_half_raw[i-1],
np = tooth_half_raw[i+1]
)
if (p.x > pp.x && p.x > np.x)
i
],
// Strip "jaggies" if found. // Strip "jaggies" if found.
tooth_half = len(minima)<2? tooth_half_raw : [ strip_left = function(path,i)
for (i = idx(tooth_half_raw)) i > len(path)? [] :
let(p = tooth_half_raw[i]) norm(path[i]) >= prad? [for (j=idx(path)) if(j>=i) path[j]] :
if (i <= minima[0] || i >= last(minima)) let(
p angs = [
], for (j=[i+1:1:len(path)-1]) let(
p = path[i],
np = path[j],
r = norm(np),
a = v_theta(np-p)
) if(r<prad) a
],
mti = !angs? 0 : min_index(angs),
out = concat([path[i]], strip_left(path, i + mti + 1))
) out,
tooth_half = strip_left(tooth_half_raw, 0),
// Mirror the tooth to complete it. // Mirror the tooth to complete it.
tooth = deduplicate([ tooth = deduplicate([