Rewrote worm_gear() function.

This commit is contained in:
Revar Desmera 2023-08-31 02:20:27 -07:00
parent 4492b35f8e
commit 7dbf5cee1d

View file

@ -2193,7 +2193,6 @@ module bevel_gear(
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 20 // pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 20
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle. Default: 0 // backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle. Default: 0
// clearance = Clearance gap at the bottom of the inter-tooth valleys. Default: module/4 // clearance = Clearance gap at the bottom of the inter-tooth valleys. Default: module/4
// profile_shift = Profile shift factor x. Default: 0
// diam_pitch = The diametral pitch, or number of teeth per inch of pitch diameter. Note that the diametral pitch is a completely different thing than the pitch diameter. // diam_pitch = The diametral pitch, or number of teeth per inch of pitch diameter. Note that the diametral pitch is a completely different thing than the pitch diameter.
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth. // mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
@ -2217,7 +2216,6 @@ function worm(
pressure_angle, pressure_angle,
backlash=0, backlash=0,
clearance, clearance,
profile_shift=0,
diam_pitch, diam_pitch,
mod, mod,
pitch, pitch,
@ -2249,7 +2247,7 @@ function worm(
clearance=clearance, clearance=clearance,
backlash=backlash, backlash=backlash,
helical=helical, helical=helical,
profile_shift=profile_shift profile_shift=0
), 1, -2) ), 1, -2)
), ),
rack_profile = [ rack_profile = [
@ -2289,7 +2287,6 @@ module worm(
pressure_angle, pressure_angle,
backlash=0, backlash=0,
clearance, clearance,
profile_shift=0,
pitch, pitch,
diam_pitch, diam_pitch,
mod, mod,
@ -2300,7 +2297,6 @@ module worm(
) { ) {
circ_pitch = _inherit_gear_pitch("worm()", pitch, circ_pitch, diam_pitch, mod); circ_pitch = _inherit_gear_pitch("worm()", pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle); PA = _inherit_gear_pa(pressure_angle);
profile_shift = auto_profile_shift(starts,PA,profile_shift=profile_shift);
checks = checks =
assert(is_integer(starts) && starts>0) assert(is_integer(starts) && starts>0)
assert(is_finite(l) && l>0) assert(is_finite(l) && l>0)
@ -2309,8 +2305,7 @@ module worm(
assert(clearance==undef || (is_finite(clearance) && clearance>=0)) assert(clearance==undef || (is_finite(clearance) && clearance>=0))
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(gear_spin)) assert(is_finite(gear_spin));
assert(is_finite(profile_shift) && abs(profile_shift)<1);
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);
vnf = worm( vnf = worm(
@ -2321,7 +2316,6 @@ module worm(
pressure_angle=PA, pressure_angle=PA,
backlash=backlash, backlash=backlash,
clearance=clearance, clearance=clearance,
profile_shift=profile_shift,
mod=mod mod=mod
); );
attachable(anchor,spin,orient, d=d, l=l) { attachable(anchor,spin,orient, d=d, l=l) {
@ -2585,112 +2579,109 @@ function worm_gear(
circ_pitch, circ_pitch,
teeth, teeth,
worm_diam, worm_diam,
worm_starts = 1, worm_starts=1,
worm_arc = 60, worm_arc=60,
crowning = 0.1, crowning=0.1,
left_handed = false, left_handed=false,
pressure_angle, pressure_angle,
backlash = 0, backlash=0,
clearance, clearance,
profile_shift="auto", profile_shift="auto",
slices = 10, slices=10,
gear_spin=0, gear_spin=0,
pitch, pitch,
diam_pitch, diam_pitch,
mod, mod,
anchor = CENTER, anchor=CTR,
spin = 0, spin=0,
orient = UP orient=UP
) = ) =
assert(worm_arc >= 10 && worm_arc <= 60)
let( let(
circ_pitch = _inherit_gear_pitch("worm_gear()", pitch, circ_pitch, diam_pitch, mod), circ_pitch = _inherit_gear_pitch("worm_gear()", pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle), PA = _inherit_gear_pa(pressure_angle),
profile_shift = auto_profile_shift(teeth,PA,profile_shift=profile_shift) profile_shift = auto_profile_shift(teeth,PA,profile_shift=profile_shift)
) )
assert(is_integer(teeth) && teeth>10)
assert(is_finite(worm_diam) && worm_diam>0) assert(is_finite(worm_diam) && worm_diam>0)
assert(is_integer(teeth) && teeth>7)
assert(is_finite(worm_arc) && worm_arc>0 && worm_arc <= 60)
assert(is_integer(worm_starts) && worm_starts>0) assert(is_integer(worm_starts) && worm_starts>0)
assert(is_finite(worm_arc) && worm_arc>0 && worm_arc<90)
assert(is_finite(crowning) && crowning>=0)
assert(is_bool(left_handed)) assert(is_bool(left_handed))
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.") assert(is_finite(backlash))
assert(is_finite(crowning) && crowning>=0)
assert(clearance==undef || (is_finite(clearance) && clearance>=0)) assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0) assert(is_finite(profile_shift))
//assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(slices==undef || (is_integer(slices) && slices>0))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_spin))
let( let(
gear_arc = 2 * PA,
helical = asin(worm_starts * circ_pitch / PI / worm_diam), helical = asin(worm_starts * circ_pitch / PI / worm_diam),
pr = pitch_radius(circ_pitch, teeth,helical), full_tooth = apply(
hob_rad = worm_diam / 2 + crowning, zrot(90) * scale(0.99),
thickness = worm_gear_thickness(circ_pitch=circ_pitch, teeth=teeth, worm_diam=worm_diam, worm_arc=worm_arc, crowning=crowning, clearance=clearance), _gear_tooth_profile(
tooth_profile = _gear_tooth_profile( circ_pitch, teeth=teeth,
circ_pitch=circ_pitch, pressure_angle=PA,
teeth=teeth, profile_shift=-profile_shift,
pressure_angle=PA, clearance=clearance,
clearance=clearance, helical=helical,
backlash=backlash, center=true
helical=helical, )
profile_shift=profile_shift,
internal=true,
center=true
), ),
tbot = min(column(tooth_profile,1)), ftl = len(full_tooth),
arcthick = hob_rad * sin(worm_arc/2) * 2, tooth_half1 = (select(full_tooth, 0, ftl/2-1)),
twist = sin(helical)*arcthick / (2*PI*pr) * 360, tooth_half2 = (select(full_tooth, ftl/2, -1)),
profiles = [ tang = 360 / teeth,
for (slice = [0:1:slices]) let( rteeth = quantdn(teeth * gear_arc / 360, 2) / 2 + 0.5,
u = slice/slices - 0.5 pr = pitch_radius(circ_pitch, teeth, helical=helical),
) [ rows = [
for (i = [0:1:teeth-1]) each for (data = [[tooth_half1,1], [tooth_half2,-1]])
apply( let (
zrot(-i*360/teeth + twist*u - 0.5) * tooth_half = data[0],
right(pr+hob_rad) * dir = data[1]
yrot(u*worm_arc) * )
left(hob_rad) * for (pt = tooth_half) [
zrot(-90) * for (i = [0:1:slices])
back(tbot) * let (
scale(pow(cos(u*worm_arc),2)) * u = i / slices,
fwd(tbot), w_ang = worm_arc * (u - 0.5),
path3d(tooth_profile) g_ang_delta = w_ang/360 * tang * worm_starts * (left_handed?1:-1),
) m = zrot(dir*(rteeth-0.0)*tang, cp=[worm_diam/2+pr,0,0]) *
left(crowning) *
yrot(w_ang) *
right(worm_diam/2+crowning) *
zrot(-1*dir*(rteeth+0.0)*tang+g_ang_delta, cp=[pr,0,0]) *
xrot(180)
) apply(m, point3d(pt))
] ]
], ],
top_verts = last(profiles), zs = column(flatten(rows),2),
bot_verts = profiles[0], minz = min(zs),
face_pts = len(tooth_profile), maxz = max(zs),
gear_pts = face_pts * teeth, zmax = max(abs(minz), abs(max(zs)))+0.1,
top_faces =[ twang = modang(v_theta(rows[0][0]) - v_theta(last(rows[0]))) / (maxz-minz),
for (i=[0:1:teeth-1], j=[0:1:(face_pts/2)-2]) each [ tip_pt1 = rows[ftl/2][0],
[i*face_pts+j, (i+1)*face_pts-j-1, (i+1)*face_pts-j-2], tip_pt2 = rows[ftl/2+1][0]
[i*face_pts+j, (i+1)*face_pts-j-2, i*face_pts+j+1] )
assert(tip_pt1.x < tip_pt2.x, "worm_arc is too large to make a viable worm gear tooth geometry.")
let(
tooth_rows = [
for (row = rows) [
zrot(twang*(zmax-row[0].z), p=[row[0].x, row[0].y, zmax]),
each row,
zrot(twang*(-zmax-last(row).z), p=[last(row).x, last(row).y, -zmax]),
], ],
for (i=[0:1:teeth-1]) each [
[gear_pts, (i+1)*face_pts-1, i*face_pts],
[gear_pts, ((i+1)%teeth)*face_pts, (i+1)*face_pts-1]
]
], ],
sides_vnf = vnf_vertex_array(profiles, caps=false, col_wrap=true, style="min_edge"), gear_rows = [
vnf1 = vnf_join([ for (i = [0:1:teeth-1])
[ let(
[each top_verts, [0,0,top_verts[0].z]], m = zrot(i*tang) *
[for (x=top_faces) reverse(x)] back(pr) *
], zrot(-90) *
[ left(worm_diam/2)
[each bot_verts, [0,0,bot_verts[0].z]], )
top_faces for (row = tooth_rows)
], apply(m, row)
sides_vnf ],
]), vnf1 = vnf_vertex_array(transpose(gear_rows), col_wrap=true, caps=true),
m = product([ vnf = apply(zrot(gear_spin), vnf1)
zrot(gear_spin), ) reorient(anchor,spin,orient, r=pr, h=2*zmax, p=vnf);
if (left_handed) xflip(),
zrot(90),
]),
vnf = apply(m,vnf1)
) reorient(anchor,spin,orient, r=pr, l=thickness, p=vnf);
module worm_gear( module worm_gear(
@ -2702,11 +2693,11 @@ module worm_gear(
crowning = 0.1, crowning = 0.1,
left_handed = false, left_handed = false,
pressure_angle, pressure_angle,
clearance,
backlash = 0, backlash = 0,
shaft_diam = 0, clearance,
slices = 10,
profile_shift="auto", profile_shift="auto",
slices = 10,
shaft_diam = 0,
gear_spin=0, gear_spin=0,
pitch, pitch,
diam_pitch, diam_pitch,
@ -3852,5 +3843,73 @@ function gear_shorten_skew(teeth1,teeth2,helical1,helical2,profile_shift1="auto"
profile_shift1+profile_shift2-y; profile_shift1+profile_shift2-y;
module _show_gear_tooth_profile(
circ_pitch,
teeth,
pressure_angle=20,
profile_shift,
helical=0,
internal=false,
clearance,
backlash=0,
show_verts=false,
diam_pitch,
mod
) {
mod = module_value(circ_pitch=circ_pitch, diam_pitch=diam_pitch, mod=mod);
profile_shift = default(profile_shift, auto_profile_shift(teeth, pressure_angle, helical));
or = outer_radius(mod=mod, teeth=teeth, clearance=clearance, helical=helical, profile_shift=profile_shift, internal=internal);
pr = pitch_radius(mod=mod, teeth=teeth, helical=helical);
rr = _root_radius(mod=mod, teeth=teeth, helical=helical, profile_shift=profile_shift, clearance=clearance, internal=internal);
br = _base_radius(mod=mod, teeth=teeth, helical=helical, pressure_angle=pressure_angle);
tang = 360/teeth;
rang = tang * 1.075;
tsize = (or-rr) / 20;
clear = (1-profile_shift)*mod;
tooth = _gear_tooth_profile(
mod=mod, teeth=teeth,
pressure_angle=pressure_angle,
clearance=clearance,
backlash=backlash,
helical=helical,
internal=internal,
profile_shift=profile_shift
);
$fn=360;
union() {
color("cyan") { // Pitch circle
stroke(arc(r=pr,start=90-rang/2,angle=rang), width=0.05);
zrot(-tang/2*1.10) back(pr) text("pitch", size=tsize, halign="left", valign="center");
}
color("lightgreen") { // Outer and Root circles
stroke(arc(r=or,start=90-rang/2,angle=rang), width=0.05);
stroke(arc(r=rr,start=90-rang/2,angle=rang), width=0.05);
zrot(-tang/2*1.10) back(or) text("tip", size=tsize, halign="left", valign="center");
zrot(-tang/2*1.10) back(rr) text("root", size=tsize, halign="left", valign="center");
}
color("#fcf") { // Base circle
stroke(arc(r=br,start=90-rang/2,angle=rang), width=0.05);
zrot(tang/2*1.10) back(br) text("base", size=tsize, halign="right", valign="center");
}
color("#ddd") { // Clearance area
if (internal) {
dashed_stroke(arc(r=pr+clear, start=90-rang/2, angle=rang), width=0.05);
back((pr+clear+or)/2) text("clearance", size=tsize, halign="center", valign="center");
} else {
dashed_stroke(arc(r=pr-clear, start=90-rang/2, angle=rang), width=0.05);
back((pr-clear+rr)/2) text("clearance", size=tsize, halign="center", valign="center");
}
}
color("#ddd") { // Tooth width markers
stroke([polar_to_xy(min(rr,br)-mod/10,90-180/teeth),polar_to_xy(or+mod/10,90-180/teeth)], width=0.05, closed=true);
stroke([polar_to_xy(min(rr,br)-mod/10,90+180/teeth),polar_to_xy(or+mod/10,90+180/teeth)], width=0.05, closed=true);
}
zrot_copies([0]) { // Tooth profile overlay
stroke(tooth, width=0.1, dots=(show_verts?"dot":false), endcap_color1="green");
}
}
}
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap