BOSL2/gears.scad

2914 lines
130 KiB
OpenSCAD
Raw Normal View History

2017-08-30 00:00:16 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////
2021-03-01 09:29:41 +00:00
// LibFile: gears.scad
// Spur Gears, Bevel Gears, Racks, Worms and Worm Gears.
2022-04-21 04:26:20 +00:00
// Inspired by code by Leemon Baird, 2011, Leemon@Leemon.com
// Includes:
// include <BOSL2/std.scad>
2021-03-01 09:29:41 +00:00
// include <BOSL2/gears.scad>
// FileGroup: Parts
// FileSummary: Gears, racks, worms, and worm gears.
2017-08-30 00:00:16 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////
_GEAR_PITCH = 5;
_GEAR_HELICAL = 0;
_GEAR_THICKNESS = 10;
_GEAR_PA = 20;
$parent_gear_type = undef;
$parent_gear_pitch = undef;
$parent_gear_teeth = undef;
$parent_gear_pa = undef;
$parent_gear_helical = undef;
$parent_gear_thickness = undef;
$parent_gear_dir = undef;
$parent_gear_travel = 0;
function _inherit_gear_param(name, val, pval, dflt, invert=false) =
is_undef(val)
? is_undef(pval)
? dflt
: (invert?-1:1)*pval
: is_undef(pval)
? assert(is_finite(val), str("Invalid ",name," value: ",val))
val
: (invert?-1:1)*val;
function _inherit_gear_pitch(fname,pitch,circ_pitch,diam_pitch,mod,warn=true) =
pitch != undef?
assert(is_finite(pitch) && pitch>0)
warn? echo(str(
"WARNING: The use of the argument pitch= in ", fname,
" is deprecated. Please use circ_pitch= instead."
)) pitch : pitch :
circ_pitch != undef?
assert(is_finite(circ_pitch) && circ_pitch>0)
circ_pitch :
diam_pitch != undef?
assert(is_finite(diam_pitch) && diam_pitch>0)
pitch_value(diam_pitch=diam_pitch) :
mod != undef?
assert(is_finite(mod) && mod>0)
pitch_value(mod) :
$parent_gear_pitch != undef? $parent_gear_pitch :
5;
function _inherit_gear_pa(pressure_angle) =
_inherit_gear_param("pressure_angle", pressure_angle, $parent_gear_pa, dflt=20);
function _inherit_gear_helical(helical,invert=false) =
_inherit_gear_param("helical", helical, $parent_gear_helical, dflt=0, invert=invert);
function _inherit_gear_thickness(thickness) =
_inherit_gear_param("thickness", thickness, $parent_gear_thickness, dflt=10);
// Section: Terminology
// The outline of a gear is a smooth circle (the "pitch circle") which has
// mountains and valleys added so it is toothed. There is an inner
// circle (the "root circle") that touches the base of all the teeth, an
// outer circle that touches the tips of all the teeth, and the invisible
// pitch circle in between them. There is also a "base circle", which can
// be smaller than all three of the others, which controls the shape of
// the teeth. The side of each tooth lies on the path that the end of a
// string would follow if it were wrapped tightly around the base circle,
// then slowly unwound. That shape is an "involute", which gives this
// type of gear its name.
2023-07-23 02:57:52 +00:00
// Section: Involute Spur Gears
// The simplest gear form is the involute spur gear, which is an extrusion of a two dimensional form.
2023-07-27 03:29:52 +00:00
// Figure(3D,Med,NoAxes): Involute Spur Gear
2023-07-25 01:02:52 +00:00
// spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25);
2023-07-23 02:57:52 +00:00
// Continues:
2023-07-25 01:02:52 +00:00
// The term "involute" refers to the shape of the teeth: the curves of the teeth involutes of circles,
// which are curves that optimize gear performance.
2023-07-27 03:40:00 +00:00
// Figure(2D,Med,NoAxes,VPT=[8,74,0],VPR=[0,0,0],VPD=150): The three marked circles are key references on gear teeth. The pitch circle, which is roughly in the middle of the teeth, is the reference used to define the pitch of teeth on the gear. The pressure angle is the angle the tooth makes with the pitch circle. In this example, the pressure angle is 20 degrees as shown by the red lines.
2023-07-23 02:57:52 +00:00
// $fn=128;
// intersection(){
// spur_gear2d(mod=5,teeth=30,pressure_angle=20);
// back(82)rect([45, 20],anchor=BACK);
// }
// color("black"){
2023-07-25 01:02:52 +00:00
// stroke(arc(r=_root_radius(mod=5,teeth=30),angle=[70,110]),width=.25);
2023-07-23 02:57:52 +00:00
// stroke(arc(r=pitch_radius(mod=5,teeth=30),angle=[70,110]),width=.25);
// stroke(arc(r=outer_radius(mod=5,teeth=30),angle=[70,110]),width=.25);
2023-07-25 01:02:52 +00:00
// back(63.5)right(24.2)text("root circle",size=2.5);
2023-07-23 02:57:52 +00:00
// back(69.5)right(26.5)text("pitch circle",size=2.5);
// back(74)right(28)text("outer circle",size=2.5);
// }
// base = _base_radius(mod=5, teeth=30);
// pitchpt = pitch_radius(mod=5, teeth=30);
// color("blue")rot(98.1)stroke([[base,0], [base+12,0]],width=0.25);
// color("red"){
// zrot(87-360/30)zrot(20,cp=[pitchpt,0])stroke([[base-5,0],[base+15,0]], width=0.25);
// zrot(87-360/30)stroke([[pitchpt,0],[pitchpt+11,0]], width=0.25);
// right(8.3)back(74)zrot(87-360/30)zrot(10,cp=[pitchpt,0]) stroke( arc(angle=[0,20],r=10.5),endcaps="arrow2",width=.25);
// back(84)right(13)text("pressure angle",size=2.5);
2023-07-26 00:16:33 +00:00
// }
2023-07-23 02:57:52 +00:00
// Continues:
// The size of the teeth can be specified as the circular pitch, the distance along the pitch circle
// from the start of one tooth to the start of the text tooth. The circular pitch can be computed as
// `PI*d/teeth` where `d` is the diameter of the pitch circle and `teeth` is the number of teeth on the gear.
// This simply divides up the pitch circle into the specified number of teeth. However, the customary
// way to specify metric gears is using the module, the number of teeth that would fit on the diameter of the gear: `m=d/teeth`.
// The module is hence the circular pitch divided by a factor of PI. A third way to specify gear sizes is the diametral pitch,
// which is the number of teeth that fit on a gear with a diameter of one inch, or PI times the number of teeth per inch.
// Note that for the module or circular pitch, larger values make larger teeth,
// but for the diametral pitch, the opposite is true. Throughout this library, module and circular pitch
// are specified basic OpenSCAD units, so if you work in millimeters and want to give circular pitch in inches, be
// sure to multiply by `INCH`. The diametral pitch is given based on inches under the assumption that OpenSCAD units are millimeters.
// .
// Basic gears as shown above will mesh when their profile circles are tangent.
// The critical requirements for two gears to mesh are that
// - The teeth are the same size
// - The pressure angles are identical
// Increasing pressure angle makes the tooth stronger, increases power transmission, and can reduce tooth interference for
// gears with a small number of teeth, but it also increases gear wear and meshing noise. Higher pressure angles also
// increase the force that tries to push the gears apart, and hence the load on the gear axles. The current standard pressure
// angle is 20 degrees. It replaces an old 14.5 degree standard.
// Figure(2D,Med,NoAxes): Teeth of the same size with different pressure angles. Note that 20 deg is the industry standard.
2023-07-26 00:16:33 +00:00
// pang = [30,20,14.5];
// ycopies(n=3,spacing=25){
2023-07-23 02:57:52 +00:00
// intersection(){
// spur_gear2d(mod=5,teeth=30,pressure_angle=pang[$idx]);
// back(82)rect([45, 20],anchor=BACK);
// }
// back(68)right(26)text(str(pang[$idx]), size=6.5);
2023-07-26 00:16:33 +00:00
// }
2023-07-23 02:57:52 +00:00
// Continues:
// In order for the gear teeth to fit together, and to allow space for lubricant, the valleys of the teeth
// are made deeper by the `clearance` distance.
2023-07-25 01:02:52 +00:00
// Figure(2D,Med,NoAxes,VPD=[5.62512,-1.33268,-0.0144912],VPR=[0,0,0],VPD=126): The clearance is extra space at the tooth valley that separates the tooth tip (in green) from the tooth valley below it. the gap between the top of the tooth (in green) and the bot
2023-07-23 02:57:52 +00:00
// intersection(){
// rack2d(mod=5, teeth=10, height=15,clearance=undef,pressure_angle=14.5);
// rect([35,20]);
// }
// color("lightgreen")render()
// intersection(){
2023-07-25 01:02:52 +00:00
// back(gear_dist(mod=5, teeth1=146,teeth2=0,profile_shift1=0))
2023-07-23 02:57:52 +00:00
// spur_gear2d(mod=5, teeth=146,clearance=undef,profile_shift=0,pressure_angle=14.5);
// rect([45,20]);
// }
// color("black"){ stroke([[-10,-5],[20,-5]], width=.25);
// stroke([[-10,-6.2],[20,-6.2]], width=.25);
// fwd(6.4)right(22)text("clearance",size=2.5);
// }
// Continues:
// Another clearance requirement can present a serious problem when the number of teeth is low. As the gear rotates, the
// teeth may interfere with each other. This may require undercutting the gear teeth to create space, which weakens the teeth.
2023-07-25 01:02:52 +00:00
// Figure(2D,Med,NoAxes,VPD=[0.042845,6.5338,-0.0144912],VPR=[0,0,0],VPD=126): The green gear with only five teeth has a severe undercut, which weakens its teeth. This undercut is necessary to avoid interference with the teeth from the other gear during rotation. Note that the yellow rack tooth is deep into the undercut space.
2023-07-23 02:57:52 +00:00
// ang=16;
// rack2d(mod=5, teeth=3, height=15,clearance=.00001,pressure_angle=14.5);
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang/360)
2023-07-25 01:02:52 +00:00
// color("lightgreen")back(gear_dist(mod=5, teeth1=5,profile_shift1=0,teeth2=0))zrot(ang)spur_gear2d(mod=5, teeth=5,clearance=.00001,profile_shift=0,pressure_angle=14.5);
2023-07-23 12:48:42 +00:00
// Subsection: Corrected Gears and Profile Shifting
2023-07-23 02:57:52 +00:00
// A solution to the problem of undercutting is to use profile shifting. Profile shifting uses a different portion of the
// involute curve to form the gear teeth, and this adjustment to the tooth form can eliminate undercutting, while
// still allowing the gear to mesh with unmodified gears. Profile shifting
// changes the diameter at which the gear meshes. A profile shift of `x` will increase the gear mesh radius by `x*m` where m
// is the gear modulus. This means that profile shifting can also be used to fine tune the spacing between gears.
// When the gear has many teeth a negative profile shift may be able to bring the
// gears slightly closer together, while still avoiding undercutting.
// .
// The minimum number of teeth to avoid undercutting is 17 for a pressure angle of 20, but it is 32 for a pressure
// angle of 14.5 degrees. It can be computed as `2/(sin(alpha))^2` where `alpha` is the pressure angle.
// By default, the gear modules produce corrected gears. You can override this by specifying the profile shift
// yourself. A small undercut maybe acceptable, for example: a rule of thumb indicates that gears as small as 14
// teeth are OK with a 20 degree pressure angle, because the undercut is too small to weaken the teeth significantly.
2023-07-25 01:02:52 +00:00
// Figure(2D,Med,NoAxes,VPD=[1.33179,10.6532,-0.0144912],VPR=[0,0,0],VPD=155.556): Basic five tooth gear form on the left. Corrected gear with profile shifting on the right. The profile shifted teeth lack the weak undercut section. The axis of the corrected gear is shifted away from the mating rack.
2023-07-23 02:57:52 +00:00
// $fn=32;
// ang1=-20;
// ang2=20;
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang1/360)
// left(3*5*PI/2)
2023-07-25 01:02:52 +00:00
// back(gear_dist(mod=5,teeth1=5,profile_shift1=0,teeth2=0))zrot(ang1){spur_gear2d(mod=5, teeth=5, profile_shift=0, pressure_angle=14.5);color("black")circle(r=1);}
2023-07-23 02:57:52 +00:00
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang2/360)
// right(3*5*PI/2)
2023-07-25 01:02:52 +00:00
// back(gear_dist(mod=5,teeth1=5,teeth2=0))zrot(ang2){spur_gear2d(mod=5, teeth=5, pressure_angle=14.5);color("black")circle(r=1);}
2023-07-23 02:57:52 +00:00
// rack2d(teeth=4, height=15, mod=5);
// Section: Helical Gears
// Helicals gears are a modification of spur gears. They can replace spur gears in any application. The teeth are cut
// following a slanted, helical path. The angled teeth engage more gradually than spur gear teeth, so they run more smoothly
// and quietly. A disadvantage of helical gears is that they have thrust along the axis of the gear that must be
// accomodated. Helical gears also have more sliding friction between the meshing teeth compared to spur gears.
// Figure(Med,NoAxes): A Helical Gear
// spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=-29);
// Continues:
// Helical gears have the same compatibility requirements as spur gears, with the additional requirement that
// the helical angles must be opposite each other, so a gear with a helical angle of 25 must mesh with one
2023-07-25 01:02:52 +00:00
// that has an angle of -25. The separation between gears also has an additional correction that depends on the cosine of
// the helical angle, so it will be different from a spur gear with the same parameters. This can allow you to
// make much bigger spacing adjustments than are possible with profile shifting---without changing the tooth count.
// The effective pressure angle of helical gears is larger than the nominal pressure angle. This can make it possible
// to avoid undercutting without having to use profile shifting, so smaller tooth count gears can be more effective
// using the helical form.
// Figure(Anim,Frames=10,VPD=[43.8006,15.9214,3.52727],VPR=[62.3,0,20.3],VPD=446.129): Meshing compatible helical gears
2023-07-23 02:57:52 +00:00
// zrot($t*360/18)spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=-29);
2023-07-25 01:02:52 +00:00
// right(gear_dist(mod=5,teeth1=18,teeth2=18,helical=29))
// zrot(360/18/2)zrot(-$t*360/18)spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=29);
2023-07-23 02:57:52 +00:00
// Continues:
// Helical gears can mesh in a second manner that is different from spur gears at skew, or crossed axis. These are also
// sometimes called "screw gears". In fact, the general requirement for two helical gears to mesh is that the angle
// between the gears' axes must equal the sum of the helical angles of the two gears, thus for parallel axes, the helical
// angles must sum to zero.
2023-07-25 01:02:52 +00:00
// Figure(Anim,Frames=10): NOT WORKING NOW Two helical gears with 22.5 degree helical angle meshing with their axes at a 45 degree angle.
// //color("lightblue") zrot($t*360/18)spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=22.5);
// // right(2*mesh_radius(mod=5,teeth=18,helical=22.5))xrot(45)zrot(360/18/2)zrot(-$t*360/18)spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=22.5);
2023-07-23 02:57:52 +00:00
// Section: Herringbone Gears
// The herringbone gear addresses the problem of axial forces that afflict helical gears by having one section that slopes to the
// right and another that slopes to the left. Herringbone gears also have the advantage of being self-aligning.
// Figure(Med,NoAxes): A herringbone gear
// spur_gear(mod=5,teeth=16,pressure_angle=20,thickness=35,helical=-20,herringbone=true);
2022-03-28 03:06:42 +00:00
// Section: Gears
2022-03-28 03:06:42 +00:00
// Function&Module: spur_gear()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a spur gear, helical gear, or internal ring gear.
// SynTags: Geom, VNF
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
2022-03-28 03:06:42 +00:00
// Usage: As a Module
// spur_gear(circ_pitch, teeth, thickness, [shaft_diam], [hide=], [pressure_angle=], [clearance=], [backlash=], [helical=], [slices=], [internal=], [herringbone=]) [ATTACHMENTS];
2022-04-09 01:06:14 +00:00
// spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...) [ATTACHMENTS];
2022-03-28 03:06:42 +00:00
// Usage: As a Function
// vnf = spur_gear(circ_pitch, teeth, thickness, [shaft_diam=], ...);
// vnf = spur_gear(mod=, teeth=, thickness=, [shaft_diam=], ...);
// Description:
// Creates a involute spur gear, helical gear, or a mask for an internal ring gear. The module `spur_gear()` gives an involute
2022-03-28 03:06:42 +00:00
// spur gear, with reasonable defaults for all the parameters. Normally, you should just choose the
2023-06-18 13:22:41 +00:00
// first 4 parameters, and let the rest be default values. Spur gears have straight teeth and
// mesh together on parallel shafts without creating any axial thrust. The teeth engage suddenly across their
// entire width, creating stress and noise. Helical gears have angled teeth and engage more gradually, so they
// run more smoothly and quietly, however they do produce thrust along the gear axis. This can be
// circumvented using herringbone or double helical gears, which have no axial thrust and also self-align.
// Helical gears can mesh along shafts that are not parallel, where the angle between the shafts is
// the sum of the helical angles of the two gears.
// .
2023-06-18 13:22:41 +00:00
// The module `spur_gear()` gives a gear in
2022-03-28 03:06:42 +00:00
// the XY plane, centered on the origin, with one tooth centered on the positive Y axis. The most
2023-07-25 01:02:52 +00:00
// important function is `gear_dist()`, which tells how far apart to space gears that are meshing, and
2022-03-28 03:06:42 +00:00
// `outer_radius()`, which gives the size of the region filled by the gear. A gear has a "pitch
// circle", which is an invisible circle that cuts through the middle of each tooth (though not the
// exact center). In order for two gears to mesh, their pitch circles should just touch. So the
// distance between their centers should be `mesh_radius()` for one, plus `mesh_radius()` for the
// other, which gives the overall meshing distance. In order for two gears to mesh, they must
2022-03-28 03:06:42 +00:00
// have the same `pitch` and `pressure_angle` parameters. `pitch` gives the number of millimeters
// of arc around the pitch circle covered by one tooth and one space between teeth. The
// `pressure_angle` controls how flat or bulged the sides of the teeth are. Common values include
// 14.5 degrees and 20 degrees, and occasionally 25. The default here is 20 degrees.
2022-03-28 03:06:42 +00:00
// The ratio of `teeth` for two meshing gears gives how many times one will make a full revolution
// when the the other makes one full revolution. If the two numbers are coprime (i.e. are not both
// divisible by the same number greater than 1), then every tooth on one gear will meet every tooth
// on the other, for more even wear. So coprime numbers of teeth are good.
// Normally, If the number of teeth is too few, gear tooth shapes may be undercut to allow meshing
// with other gears. If this is the case, profile shifting will automatically be applies to enlarge
// the teeth, removing the undercut. This may add to the distance needed between gears.
// If you with to override this correction, you can use `profile_shift=0`, or set it to a specific
// value like 0.5.
// Arguments:
// circ_pitch = The circular pitch, or distance in mm between teeth around the pitch circle.
2022-03-28 03:06:42 +00:00
// teeth = Total number of teeth around the entire perimeter
// thickness = Thickness of gear in mm
// shaft_diam = Diameter of the hole in the center, in mm. Default: 0 (no shaft hole)
// ---
// hide = Number of teeth to delete to make this only a fraction of a circle
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// helical = Teeth are slanted around the spur gear at this angle away from the gear axis of rotation.
// slices = Number of vertical layers to divide gear into. Useful for refining gears with `helical`.
// 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.
// internal = If true, create a mask for difference()ing from something else.
// profile_shift = Profile shift factor x.
// herringbone = If true, and helical is set, creates a herringbone gear.
2022-03-28 03:06:42 +00:00
// 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`
// Side Effects:
// If internal is true then the default tag is "remove"
2022-03-28 03:06:42 +00:00
// Example: Spur Gear
// spur_gear(circ_pitch=5, teeth=20, thickness=8, shaft_diam=5);
2022-03-28 03:06:42 +00:00
// Example: Metric Gear
// spur_gear(mod=2, teeth=20, thickness=8, shaft_diam=5);
// Example: Helical Gear
// spur_gear(
// circ_pitch=5, teeth=20, thickness=10,
2022-03-28 03:06:42 +00:00
// shaft_diam=5, helical=-30, slices=12,
// $fa=1, $fs=1
// );
// Example: Herringbone Gear
// spur_gear(
// circ_pitch=5, teeth=20, thickness=10, shaft_diam=5,
// helical=30, herringbone=true, slices=5
// );
2023-07-25 01:02:52 +00:00
// Example(2D,Big): Effects of Profile Shifting.
// circ_pitch=5; teeth=7; thick=10; shaft=5; strokewidth=0.2;
// pr = pitch_radius(circ_pitch, teeth);
// left(10) {
// profile_shift = 0;
2023-07-25 01:02:52 +00:00
// d = gear_dist(circ_pitch,teeth,0,profile_shift1=profile_shift);
// back(d) spur_gear(circ_pitch, teeth, thick, shaft, profile_shift=profile_shift);
// rack(circ_pitch, teeth=3, thickness=thick, height=5, orient=BACK);
// color("black") up(thick/2) linear_extrude(height=0.1) {
2023-07-25 01:02:52 +00:00
// back(d) dashed_stroke(circle(r=pr), width=strokewidth, closed=true);
// dashed_stroke([[-7.5,0],[7.5,0]], width=strokewidth);
// }
// }
// right(10) {
// profile_shift = 0.59;
2023-07-25 01:02:52 +00:00
// d = gear_dist(circ_pitch,teeth,0,profile_shift1=profile_shift);
// back(d) spur_gear(circ_pitch, teeth, thick, shaft, profile_shift=profile_shift);
// rack(circ_pitch, teeth=3, thickness=thick, height=5, orient=BACK);
// color("black") up(thick/2) linear_extrude(height=0.1) {
2023-07-25 01:02:52 +00:00
// back(d)
// dashed_stroke(circle(r=pr), width=strokewidth, closed=true);
// dashed_stroke([[-7.5,0],[7.5,0]], width=strokewidth);
// }
// }
2022-03-28 03:06:42 +00:00
// Example(Anim,Frames=8,VPT=[0,30,0],VPR=[0,0,0],VPD=300): Assembly of Gears
2023-07-25 01:02:52 +00:00
// $fn=12;
2022-03-28 03:06:42 +00:00
// n1 = 11; //red gear number of teeth
// n2 = 20; //green gear
// n3 = 6; //blue gear
2022-03-28 03:06:42 +00:00
// n4 = 16; //orange gear
// n5 = 9; //gray rack
// circ_pitch = 9; //all meshing gears need the same `circ_pitch` (and the same `pressure_angle`)
2022-03-28 03:06:42 +00:00
// thickness = 6;
// hole = 3;
// rack_base = 12;
2023-07-25 01:02:52 +00:00
// d12 = gear_dist(circ_pitch,teeth1=n1,teeth2=n2);
// d13 = gear_dist(circ_pitch,teeth1=n1,teeth2=n3);
// d14 = gear_dist(circ_pitch,teeth1=n1,teeth2=n4);
// d1r = gear_dist(circ_pitch,teeth1=n1,teeth2=0);
2022-03-28 03:06:42 +00:00
// a1 = $t * 360 / n1;
// a2 = -$t * 360 / n2 + 180/n2;
// a3 = -$t * 360 / n3 - 3*90/n3;
// a4 = -$t * 360 / n4 - 3.5*180/n4;
// color("#f77") zrot(a1) spur_gear(circ_pitch,n1,thickness,hole);
2023-07-25 01:02:52 +00:00
// color("#7f7") back(d12) zrot(a2) spur_gear(circ_pitch,n2,thickness,hole);
// color("#77f") right(d13) zrot(a3) spur_gear(circ_pitch,n3,thickness,hole);
// color("#fc7") left(d14) zrot(a4) spur_gear(circ_pitch,n4,thickness,hole,hide=n4-3);
// color("#ccc") fwd(d1r) right(circ_pitch*$t)
// rack(pitch=circ_pitch,teeth=n5,thickness=thickness,height=rack_base,anchor=CENTER,orient=BACK);
2023-07-25 01:02:52 +00:00
// Example: Helical gears meshing with non-parallel shafts BROKEN
// // ang1 = 30;
// // ang2 = 10;
// // circ_pitch = 5;
// // n = 20;
// // r1 = mesh_radius(circ_pitch,n,helical=ang1);
// // r2 = mesh_radius(circ_pitch,n,helical=ang2);
// // left(r1) spur_gear(
// // circ_pitch, teeth=n, thickness=10,
// // shaft_diam=5, helical=ang1, slices=12,
// // gear_spin=-90
// // );
// // right(r2)
// // xrot(ang1+ang2)
// // spur_gear(
// // circ_pitch=circ_pitch, teeth=n, thickness=10,
// // shaft_diam=5, helical=ang2, slices=12,
// // gear_spin=90-180/n
// // );
// Example(Anim,Frames=36,VPT=[0,0,0],VPR=[55,0,25],VPD=375): Planetary Gear Assembly
// rteeth=56; pteeth=16; cteeth=24;
// circ_pitch=5; thick=10; pa=20;
2023-07-25 01:02:52 +00:00
// gd = gear_dist(circ_pitch, cteeth, pteeth);
// ring_gear(
// circ_pitch=circ_pitch,
// teeth=rteeth,
// thickness=thick,
// pressure_angle=pa);
// for (a=[0:3]) {
2023-07-25 01:02:52 +00:00
// zrot($t*90+a*90) back(gd) {
// color("green")
// spur_gear(
// circ_pitch=circ_pitch,
// teeth=pteeth,
// thickness=thick,
// shaft_diam=5,
// pressure_angle=pa,
// spin=-$t*90*rteeth/pteeth);
// }
// }
// color("orange")
// zrot($t*90*rteeth/cteeth+$t*90+180/cteeth)
// spur_gear(
// circ_pitch=circ_pitch,
// teeth=cteeth,
// thickness=thick,
// shaft_diam=5,
// pressure_angle=pa);
2023-07-25 01:02:52 +00:00
//
2022-03-28 03:06:42 +00:00
function spur_gear(
circ_pitch,
teeth,
thickness,
2022-03-28 03:06:42 +00:00
shaft_diam = 0,
hide = 0,
pressure_angle,
clearance,
2022-03-28 03:06:42 +00:00
backlash = 0.0,
helical,
interior,
internal,
profile_shift,
slices,
herringbone=false,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
pitch,
gear_spin = 0,
2022-03-28 03:06:42 +00:00
anchor = CENTER,
spin = 0,
orient = UP
) =
let(
dummy = !is_undef(interior) ? echo("In spur_gear(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0,
internal = first_defined([internal,interior,false]),
circ_pitch = _inherit_gear_pitch("spur_gear()", pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle),
helical = _inherit_gear_helical(helical, invert=!internal),
thickness = _inherit_gear_thickness(thickness),
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA))
)
assert(is_integer(teeth) && teeth>3)
assert(is_finite(thickness) && thickness>0)
assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_integer(hide) && hide>=0 && hide<teeth)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
assert(is_bool(herringbone))
assert(slices==undef || (is_integer(slices) && slices>0))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_spin))
let(
pr = pitch_radius(circ_pitch, teeth, helical),
circum = 2 * PI * pr,
twist = 360*thickness*tan(helical)/circum,
slices = default(slices, ceil(twist/360*segs(pr)+1)),
rgn = spur_gear2d(
circ_pitch = circ_pitch,
2022-03-28 03:06:42 +00:00
teeth = teeth,
pressure_angle = PA,
2022-03-28 03:06:42 +00:00
hide = hide,
helical = helical,
2022-03-28 03:06:42 +00:00
clearance = clearance,
backlash = backlash,
internal = internal,
profile_shift = profile_shift,
shaft_diam = shaft_diam
2022-03-28 03:06:42 +00:00
),
rvnf = herringbone
? zrot(twist/2, p=linear_sweep(rgn, height=thickness, twist=twist, slices=slices, center=true))
: let(
wall_vnf = linear_sweep(rgn, height=thickness/2, twist=twist/2, slices=ceil(slices/2), center=false, caps=false),
cap_vnf = vnf_from_region(rgn, transform=up(thickness/2)*zrot(twist/2))
)
vnf_join([
wall_vnf, zflip(p=wall_vnf),
cap_vnf, zflip(p=cap_vnf),
]),
vnf = zrot(gear_spin, p=rvnf)
) reorient(anchor,spin,orient, h=thickness, r=pr, p=vnf);
2022-03-28 03:06:42 +00:00
module spur_gear(
circ_pitch,
teeth,
thickness,
2022-03-28 03:06:42 +00:00
shaft_diam = 0,
hide = 0,
pressure_angle,
clearance,
2022-03-28 03:06:42 +00:00
backlash = 0.0,
helical,
internal,
interior,
profile_shift,
slices,
herringbone=false,
pitch,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
gear_spin = 0,
2022-03-28 03:06:42 +00:00
anchor = CENTER,
spin = 0,
orient = UP
) {
dummy = !is_undef(interior) ? echo("In spur_gear(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0;
internal = first_defined([internal,interior,false]);
circ_pitch = _inherit_gear_pitch("spur_gear()", pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical, invert=!internal);
thickness = _inherit_gear_thickness(thickness);
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA));
checks =
assert(is_integer(teeth) && teeth>3)
assert(is_finite(thickness) && thickness>0)
assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_integer(hide) && hide>=0 && hide<teeth)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
assert(is_bool(herringbone))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(slices==undef || (is_integer(slices) && slices>0))
assert(is_finite(gear_spin));
pr = pitch_radius(circ_pitch, teeth, helical);
circum = 2 * PI * pr;
twist = 360*thickness*tan(helical)/circum;
slices = default(slices, ceil(twist/360*segs(pr)+1));
default_tag("remove", internal) {
attachable(anchor,spin,orient, r=pr, l=thickness) {
zrot(gear_spin)
if (herringbone) {
zflip_copy() down(0.01)
linear_extrude(
height=thickness/2+0.01, center=false,
twist=twist/2, slices=ceil(slices/2),
convexity=teeth/2
) {
spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
pressure_angle = PA,
hide = hide,
helical = helical,
clearance = clearance,
backlash = backlash,
internal = internal,
profile_shift = profile_shift,
shaft_diam = shaft_diam
);
}
} else {
zrot(twist/2)
linear_extrude(
height=thickness, center=true,
twist=twist, slices=slices,
convexity=teeth/2
) {
spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
pressure_angle = PA,
hide = hide,
helical = helical,
clearance = clearance,
backlash = backlash,
internal = internal,
profile_shift = profile_shift,
shaft_diam = shaft_diam
);
}
2022-03-28 03:06:42 +00:00
}
union() {
$parent_gear_type = "spur";
$parent_gear_pitch = circ_pitch;
$parent_gear_teeth = teeth;
$parent_gear_pa = PA;
$parent_gear_helical = helical;
$parent_gear_thickness = thickness;
union() children();
}
2022-03-28 03:06:42 +00:00
}
}
2022-03-28 03:06:42 +00:00
}
2022-03-28 03:06:42 +00:00
// Function&Module: spur_gear2d()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a 2D spur gear or internal ring gear.
// SynTags: Geom, Region
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
2022-03-28 03:06:42 +00:00
// Usage: As Module
// spur_gear2d(circ_pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [internal=]) [ATTACHMENTS];
// spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [internal=]) [ATTACHMENTS];
2022-03-28 03:06:42 +00:00
// Usage: As Function
// rgn = spur_gear2d(circ_pitch, teeth, [hide=], [pressure_angle=], [clearance=], [backlash=], [internal=]);
// rgn = spur_gear2d(mod=, teeth=, [hide=], [pressure_angle=], [clearance=], [backlash=], [internal=]);
// Description:
// When called as a module, creates a 2D involute spur gear. When called as a function,
// returns a 2D region for the 2D involute spur gear. Normally, you should just specify the
// first 2 parameters `circ_pitch` and `teeth`, and let the rest be default values.
// Meshing gears must match in `circ_pitch`, `pressure_angle`, and `helical`, and be separated by
2023-07-25 01:02:52 +00:00
// the distance given by {{gear_dist()}}.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
2022-03-28 03:06:42 +00:00
// teeth = Total number of teeth around the spur gear.
// hide = Number of teeth to delete to make this only a fraction of a circle
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
// ---
// hide = Number of teeth to delete to make this only a fraction of a circle
2022-03-28 03:06:42 +00:00
// clearance = Gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// helical = The angle of the rack teeth away from perpendicular to the gear axis of rotation. Stretches out the tooth shapes. Used to match helical spur gear pinions. Default: 0
// internal = If true, create a mask for difference()ing from something else.
// profile_shift = Profile shift factor x.
// shaft_diam = If given, the diameter of the central shaft hole.
// 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.
2021-11-20 03:33:16 +00:00
// 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`
// Example(2D): Typical Gear Shape
// spur_gear2d(circ_pitch=5, teeth=20, shaft_diam=5);
// Example(2D): By Metric Module
// spur_gear2d(mod=2, teeth=20, shaft_diam=5);
// Example(2D): By Imperial Gear Pitch
// spur_gear2d(diam_pitch=10, teeth=20, shaft_diam=5);
// Example(2D): Lower Pressure Angle
// spur_gear2d(circ_pitch=5, teeth=20, pressure_angle=14);
// Example(2D): Partial Gear
// spur_gear2d(circ_pitch=5, teeth=20, hide=15, pressure_angle=20);
// Example(2D): Effects of Profile Shifting.
// circ_pitch=5; teeth=7; shaft=5; strokewidth=0.2;
// module the_gear(profile_shift=0) {
// $fn=72;
// pr = pitch_radius(circ_pitch,teeth);
2023-07-25 01:02:52 +00:00
// mr = gear_dist(circ_pitch,teeth,profile_shift1=profile_shift,teeth2=0);
// back(mr) {
// spur_gear2d(circ_pitch, teeth, shaft_diam=shaft, profile_shift=profile_shift);
// up(0.1) color("black")
// dashed_stroke(circle(r=pr), width=strokewidth, closed=true);
// }
// }
// module the_rack() {
// $fn=72;
// rack2d(circ_pitch, teeth=3, height=5);
// up(0.1) color("black")
// dashed_stroke([[-7.5,0],[7.5,0]], width=strokewidth);
// }
// left(10) { the_gear(0); the_rack(); }
// right(10) { the_gear(0.59); the_rack(); }
// Example(2D): Planetary Gear Assembly
// rteeth=56; pteeth=16; cteeth=24;
// circ_pitch=5; pa=20;
2023-07-25 01:02:52 +00:00
// gd = gear_dist(circ_pitch, cteeth,pteeth);
// ring_gear2d(
// circ_pitch=circ_pitch,
// teeth=rteeth,
// pressure_angle=pa);
// for (a=[0:3]) {
2023-07-25 01:02:52 +00:00
// zrot(a*90) back(gd) {
// color("green")
// spur_gear2d(
// circ_pitch=circ_pitch,
// teeth=pteeth,
// pressure_angle=pa);
// }
// }
// color("orange")
// zrot(180/cteeth)
// spur_gear2d(
// circ_pitch=circ_pitch,
// teeth=cteeth,
// pressure_angle=pa);
// Example(2D): Called as a Function
// rgn = spur_gear2d(circ_pitch=8, teeth=16, shaft_diam=5);
// region(rgn);
2021-03-01 09:29:41 +00:00
function spur_gear2d(
circ_pitch,
teeth,
hide = 0,
pressure_angle,
clearance,
backlash = 0.0,
internal,
interior,
profile_shift,
helical,
shaft_diam = 0,
pitch,
diam_pitch,
mod,
gear_spin = 0,
anchor = CENTER,
spin = 0
) = let(
dummy = !is_undef(interior) ? echo("In spur_gear2d(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0,
internal = first_defined([internal,interior,false]),
circ_pitch = _inherit_gear_pitch("spur_gear2d()", pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle),
helical = _inherit_gear_helical(helical, invert=!internal),
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA))
)
assert(is_integer(teeth) && teeth>3)
assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_integer(hide) && hide>=0 && hide<teeth)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(helical) && abs(helical)<90)
assert(is_finite(gear_spin))
let(
pr = pitch_radius(circ_pitch, teeth, helical=helical),
tooth = _gear_tooth_profile(
circ_pitch=circ_pitch,
teeth=teeth,
pressure_angle=PA,
clearance=clearance,
backlash=backlash,
profile_shift=profile_shift,
helical=helical,
internal=internal
),
perim = [
for (i = [0:1:teeth-1-hide])
each zrot(-i*360/teeth+gear_spin, p=tooth),
if (hide>0) [0,0],
],
rgn = [
list_unwrap(deduplicate(perim)),
if (shaft_diam>0 && !hide)
reverse(circle(d=shaft_diam)),
]
) reorient(anchor,spin, two_d=true, r=pr, p=rgn);
2019-06-12 02:29:39 +00:00
2021-03-01 09:29:41 +00:00
module spur_gear2d(
circ_pitch,
teeth,
hide = 0,
pressure_angle,
clearance,
backlash = 0.0,
internal,
interior,
profile_shift,
helical,
shaft_diam = 0,
pitch,
diam_pitch,
2020-10-22 08:33:45 +00:00
mod,
gear_spin = 0,
anchor = CENTER,
spin = 0
2017-08-30 00:00:16 +00:00
) {
dummy = !is_undef(interior) ? echo("In spur_gear2d(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0;
internal = first_defined([internal,interior,false]);
circ_pitch = _inherit_gear_pitch("spur_gear2d()", pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical, invert=!internal);
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA));
checks =
assert(is_integer(teeth) && teeth>3)
assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_integer(hide) && hide>=0 && hide<teeth)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(helical) && abs(helical)<90)
assert(is_finite(gear_spin));
rgn = spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
hide = hide,
pressure_angle = PA,
clearance = clearance,
helical = helical,
backlash = backlash,
profile_shift = profile_shift,
internal = internal,
shaft_diam = shaft_diam
);
pr = pitch_radius(circ_pitch, teeth, helical=helical);
attachable(anchor,spin, two_d=true, r=pr) {
zrot(gear_spin) region(rgn);
union() {
$parent_gear_type = "spur2D";
$parent_gear_pitch = circ_pitch;
$parent_gear_teeth = teeth;
$parent_gear_pa = PA;
$parent_gear_helical = helical;
$parent_gear_thickness = 0;
union() children();
}
}
}
// Module: ring_gear()
// Synopsis: Creates a 3D ring gear.
// SynTags: Geom
// Topics: Gears, Parts
// See Also: rack(), ring_gear2d(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage:
2023-07-17 20:41:56 +00:00
// ring_gear(circ_pitch, teeth, thickness, [backing], [pressure_angle=], [helical=], [herringbone=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// ring_gear(mod=, teeth=, thickness=, backing=, [pressure_angle=], [helical=], [herringbone=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// ring_gear(diam_pitch=, teeth=, thickness=, backing=, [pressure_angle=], [helical=], [herringbone=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// Description:
// Creates a 3D involute ring gear. Normally, you should just specify the
// first 3 parameters `circ_pitch`, `teeth`, and `thickness`, and let the rest be default values.
// Meshing gears must match in `circ_pitch`, `pressure_angle`, and `helical`, and be separated by
// the sum of their profile shifts and pitch radii, which can be found with `mesh_radius()`.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
// teeth = Total number of teeth around the spur gear.
// thickness = Thickness of ring gear in mm
2023-07-17 20:41:56 +00:00
// backing = The width of the ring gear backing, in mm.
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
// ---
// helical = The angle of the rack teeth away from perpendicular to the gear axis of rotation. Stretches out the tooth shapes. Used to match helical spur gear pinions. Default: 0
// herringbone = If true, and helical is set, creates a herringbone gear.
2023-07-17 20:41:56 +00:00
// profile_shift = Profile shift factor x for tooth profile.
// clearance = Gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// 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.
// 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`
2023-07-17 20:41:56 +00:00
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
// Example:
// ring_gear(circ_pitch=5, teeth=48, thickness=10);
// Example: Adjusting Backing
// ring_gear(circ_pitch=5, teeth=48, thickness=10, backing=30);
// Example(Med): Adjusting Pressure Angle
// ring_gear(circ_pitch=5, teeth=48, thickness=10, pressure_angle=28);
// Example(Med): Tooth Profile Shifting
// ring_gear(circ_pitch=5, teeth=48, thickness=10, profile_shift=0.5);
// Example(Med): Helical Ring Gear
// ring_gear(circ_pitch=5, teeth=48, thickness=10, helical=30);
// Example(Med): Herringbone Ring Gear
// ring_gear(circ_pitch=5, teeth=48, thickness=10, helical=30, herringbone=true);
module ring_gear(
circ_pitch,
teeth,
2023-07-17 20:41:56 +00:00
thickness = 10,
backing = 10,
pressure_angle,
helical,
herringbone = false,
2023-07-17 20:41:56 +00:00
profile_shift,
clearance,
backlash = 0.0,
pitch,
diam_pitch,
mod,
slices,
gear_spin = 0,
anchor = CENTER,
2023-07-17 20:41:56 +00:00
spin = 0,
orient = UP
) {
circ_pitch = _inherit_gear_pitch("ring_gear()",pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical);
thickness = _inherit_gear_thickness(thickness);
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA));
checks =
assert(is_integer(teeth) && teeth>3)
assert(is_finite(thickness) && thickness>0)
assert(is_finite(backing) && backing>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(is_finite(helical) && abs(helical)<90)
assert(is_bool(herringbone))
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(slices==undef || (is_integer(slices) && slices>0))
assert(is_finite(gear_spin));
pr = pitch_radius(circ_pitch, teeth, helical=helical);
ar = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=true);
circum = 2 * PI * pr;
twist = 360*thickness*tan(helical)/circum;
slices = default(slices, ceil(twist/360*segs(pr)+1));
2023-07-17 20:41:56 +00:00
attachable(anchor,spin,orient, h=thickness, r=pr) {
zrot(gear_spin)
if (herringbone) {
zflip_copy() down(0.01)
linear_extrude(height=thickness/2, center=false, twist=twist/2, slices=ceil(slices/2), convexity=teeth/4) {
difference() {
circle(r=ar+backing);
spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
pressure_angle = PA,
helical = helical,
clearance = clearance,
backlash = backlash,
profile_shift = profile_shift,
internal = true
);
}
}
} else {
zrot(twist/2)
linear_extrude(height=thickness,center=true, twist=twist, convexity=teeth/4) {
difference() {
circle(r=ar+backing);
spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
pressure_angle = PA,
helical = helical,
clearance = clearance,
backlash = backlash,
profile_shift = profile_shift,
internal = true
);
}
}
}
children();
}
}
// Module: ring_gear2d()
// Synopsis: Creates a 2D ring gear.
// SynTags: Geom
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage:
2023-07-17 20:41:56 +00:00
// ring_gear2d(circ_pitch, teeth, [backing], [pressure_angle=], [helical=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// ring_gear2d(mod=, teeth=, [backing=], [pressure_angle=], [helical=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// ring_gear2d(diam_pitch=, teeth=, [backing=], [pressure_angle=], [helical=], [profile_shift=], [clearance=], [backlash=]) [ATTACHMENTS];
// Description:
// Creates a 2D involute ring gear. Normally, you should just specify the
// first 2 parameters `circ_pitch` and `teeth`, and let the rest be default values.
// Meshing gears must match in `circ_pitch`, `pressure_angle`, and `helical`, and be separated by
// the sum of their profile shifts and pitch radii, which can be found with `mesh_radius()`.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
// teeth = Total number of teeth around the spur gear.
2023-07-17 20:41:56 +00:00
// backing = The width of the ring gear backing, in mm.
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
2023-07-17 20:41:56 +00:00
// ---
// helical = The angle of the rack teeth away from perpendicular to the gear axis of rotation. Stretches out the tooth shapes. Used to match helical spur gear pinions. Default: 0
// profile_shift = Profile shift factor x for tooth profile.
// clearance = Gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// 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.
// 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`
// Example(2D;Big):
// circ_pitch=5; teeth1=50; teeth2=16;
// pr1 = pitch_radius(circ_pitch, teeth1);
// pr2 = pitch_radius(circ_pitch, teeth2);
// ring_gear2d(circ_pitch=circ_pitch, teeth=teeth1);
// back(pr1-pr2) spur_gear2d(circ_pitch=circ_pitch, teeth=teeth2);
module ring_gear2d(
circ_pitch,
teeth,
2023-07-17 20:41:56 +00:00
backing = 10,
pressure_angle,
2023-07-17 20:41:56 +00:00
helical,
profile_shift,
clearance,
backlash = 0.0,
pitch,
diam_pitch,
mod,
gear_spin = 0,
anchor = CENTER,
spin = 0
) {
circ_pitch = _inherit_gear_pitch("ring_gear2d()",pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical);
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA));
checks =
assert(is_integer(teeth) && teeth>3)
assert(is_finite(backing) && backing>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(is_finite(helical) && abs(helical)<90)
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_spin));
pr = pitch_radius(circ_pitch, teeth, helical=helical);
ar = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=true);
attachable(anchor,spin, two_d=true, r=pr) {
zrot(gear_spin)
difference() {
circle(r=ar+backing);
spur_gear2d(
circ_pitch = circ_pitch,
teeth = teeth,
pressure_angle = PA,
helical = helical,
clearance = clearance,
backlash = backlash,
profile_shift = profile_shift,
internal = true
);
}
children();
}
}
2022-03-28 03:06:42 +00:00
// Function&Module: rack()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a straight or helical gear rack.
// SynTags: Geom, VNF
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: rack2d(), spur_gear(), spur_gear2d(), bevel_gear()
2022-03-28 03:06:42 +00:00
// Usage: As a Module
// rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=], [clearance=], [helical=]) [ATTACHMENTS];
// rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash]=, [clearance=], [helical=]) [ATTACHMENTS];
2022-03-28 03:06:42 +00:00
// Usage: As a Function
// vnf = rack(pitch, teeth, thickness, height, [pressure_angle=], [backlash=], [clearance=], [helical=]);
// vnf = rack(mod=, teeth=, thickness=, height=, [pressure_angle=], [backlash=], [clearance=], [helical=]);
2022-03-28 03:06:42 +00:00
// Description:
// This is used to create a 3D rack, which is a linear bar with teeth that a gear can roll along.
// A rack can mesh with any gear that has the same `pitch` and `pressure_angle`.
// When called as a function, returns a 3D [VNF](vnf.scad) for the rack.
// When called as a module, creates a 3D rack shape.
// Arguments:
// pitch = The pitch, or distance in mm between teeth along the rack. Matches up with circular pitch on a spur gear. Default: 5
2022-03-28 03:06:42 +00:00
// teeth = Total number of teeth along the rack. Default: 20
// thickness = Thickness of rack in mm (affects each tooth). Default: 5
// height = Height of rack in mm, from tooth top to back of rack. Default: 10
// ---
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 20
2022-03-28 03:06:42 +00:00
// 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.
// helical = The angle of the rack teeth away from perpendicular to the rack length. Used to match helical spur gear pinions. Default: 0
// profile_shift = Profile shift factor x.
// 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.
2022-03-28 03:06:42 +00:00
// 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`
// Extra Anchors:
// "adendum" = At the tips of the teeth, at the center of rack.
// "adendum-left" = At the tips of the teeth, at the left end of the rack.
// "adendum-right" = At the tips of the teeth, at the right end of the rack.
// "adendum-back" = At the tips of the teeth, at the back of the rack.
// "adendum-front" = At the tips of the teeth, at the front of the rack.
// "dedendum" = At the base of the teeth, at the center of rack.
// "dedendum-left" = At the base of the teeth, at the left end of the rack.
// "dedendum-right" = At the base of the teeth, at the right end of the rack.
// "dedendum-back" = At the base of the teeth, at the back of the rack.
// "dedendum-front" = At the base of the teeth, at the front of the rack.
// Example(VPR=[60,0,325],VPD=130):
// rack(pitch=5, teeth=10, thickness=5, height=5, pressure_angle=20);
// Example: Rack for Helical Gear
// rack(pitch=5, teeth=10, thickness=5, height=5, pressure_angle=20, helical=30);
// Example: Alternate Helical Gear
// rack(pitch=5, teeth=10, thickness=5, height=5, pressure_angle=20, helical=-30);
// Example: Metric Rack
// rack(mod=2, teeth=10, thickness=5, height=5, pressure_angle=20);
// Example(Anim,VPT=[0,0,12],VPD=100,Frames=6): Rack and Pinion
// teeth1 = 16; teeth2 = 16;
// pitch = 5; thick = 5; helical = 30;
// pr = pitch_radius(pitch, teeth2, helical=helical);
// right(pr*2*PI/teeth2*$t)
// rack(pitch, teeth1, thickness=thick, height=5, helical=helical);
// up(pr)
// spur_gear(
// pitch, teeth2,
// thickness=thick,
// helical=helical,
// shaft_diam=5,
// orient=BACK,
// gear_spin=180-$t*360/teeth2);
2022-03-28 03:06:42 +00:00
module rack(
pitch,
teeth,
thickness,
2022-03-28 03:06:42 +00:00
height = 10,
pressure_angle,
2022-03-28 03:06:42 +00:00
backlash = 0.0,
clearance,
helical,
profile_shift = 0,
gear_travel=0,
circ_pitch,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
anchor = CENTER,
spin = 0,
orient = UP
) {
pitch = _inherit_gear_pitch("rack()",pitch, circ_pitch, diam_pitch, mod, warn=false);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical);
thickness = _inherit_gear_thickness(thickness);
checks=
assert(is_integer(teeth) && teeth>0)
assert(is_finite(thickness) && thickness>0)
assert(is_finite(height) && height>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
//assert(is_bool(herringbone))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_travel));
trans_pitch = pitch / cos(helical);
a = _adendum(pitch, profile_shift);
d = _dedendum(pitch, clearance, profile_shift);
l = teeth * trans_pitch;
2022-03-28 03:06:42 +00:00
anchors = [
named_anchor("adendum", [0,0,a], BACK),
named_anchor("adendum-left", [-l/2,0,a], LEFT),
named_anchor("adendum-right", [ l/2,0,a], RIGHT),
named_anchor("adendum-front", [0,-thickness/2,a], DOWN),
named_anchor("adendum-back", [0, thickness/2,a], UP),
named_anchor("dedendum", [0,0,-d], BACK),
named_anchor("dedendum-left", [-l/2,0,-d], LEFT),
named_anchor("dedendum-right", [ l/2,0,-d], RIGHT),
named_anchor("dedendum-front", [0,-thickness/2,-d], DOWN),
named_anchor("dedendum-back", [0, thickness/2,-d], UP),
];
size = [l, thickness, 2*height];
attachable(anchor,spin,orient, size=size, anchors=anchors) {
right(gear_travel)
2022-03-28 03:06:42 +00:00
skew(sxy=tan(helical)) xrot(90) {
linear_extrude(height=thickness, center=true, convexity=teeth*2) {
rack2d(
pitch = pitch,
teeth = teeth,
height = height,
pressure_angle = PA,
2022-03-28 03:06:42 +00:00
backlash = backlash,
clearance = clearance,
helical = helical,
profile_shift = profile_shift
2022-03-28 03:06:42 +00:00
);
}
}
children();
}
}
function rack(
pitch,
teeth,
thickness,
2022-03-28 03:06:42 +00:00
height = 10,
pressure_angle,
2022-03-28 03:06:42 +00:00
backlash = 0.0,
clearance,
helical,
profile_shift = 0,
circ_pitch,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
gear_travel=0,
2022-03-28 03:06:42 +00:00
anchor = CENTER,
spin = 0,
orient = UP
) =
let(
pitch = _inherit_gear_pitch("rack()",pitch, circ_pitch, diam_pitch, mod, warn=false),
PA = _inherit_gear_pa(pressure_angle),
helical = _inherit_gear_helical(helical),
2023-07-20 03:29:49 +00:00
thickness = _inherit_gear_thickness(thickness)
)
assert(is_integer(teeth) && teeth>0)
assert(is_finite(thickness) && thickness>0)
assert(is_finite(height) && height>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
//assert(is_bool(herringbone))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_travel))
let(
trans_pitch = pitch / cos(helical),
a = _adendum(pitch, profile_shift),
d = _dedendum(pitch, clearance, profile_shift),
l = teeth * trans_pitch,
path = rack2d(
pitch = pitch,
teeth = teeth,
height = height,
pressure_angle = PA,
backlash = backlash,
clearance = clearance,
helical = helical,
profile_shift = profile_shift
),
vnf = linear_sweep(path, height=thickness, anchor="origin", orient=FWD),
m = product([
right(gear_travel),
if (helical) skew(sxy=tan(helical)),
]),
out = apply(m, vnf),
size = [l, thickness, 2*height],
2022-03-28 03:06:42 +00:00
anchors = [
named_anchor("adendum", [0,0,a], BACK),
named_anchor("adendum-left", [-l/2,0,a], LEFT),
named_anchor("adendum-right", [ l/2,0,a], RIGHT),
named_anchor("adendum-front", [0,-thickness/2,a], DOWN),
named_anchor("adendum-back", [0, thickness/2,a], UP),
named_anchor("dedendum", [0,0,-d], BACK),
named_anchor("dedendum-left", [-l/2,0,-d], LEFT),
named_anchor("dedendum-right", [ l/2,0,-d], RIGHT),
named_anchor("dedendum-front", [0,-thickness/2,-d], DOWN),
named_anchor("dedendum-back", [0, thickness/2,-d], UP),
]
) reorient(anchor,spin,orient, size=size, anchors=anchors, p=out);
2022-03-28 03:06:42 +00:00
// Function&Module: rack2d()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a 2D gear rack.
// SynTags: Geom, Path
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As a Module
// rack2d(pitch, teeth, height, [pressure_angle=], [backlash=], [clearance=]) [ATTACHMENTS];
// rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=], [clearance=]) [ATTACHMENTS];
2022-04-09 01:06:14 +00:00
// Usage: As a Function
// path = rack2d(pitch, teeth, height, [pressure_angle=], [backlash=], [clearance=]);
// path = rack2d(mod=, teeth=, height=, [pressure_angle=], [backlash=], [clearance=]);
// Description:
// This is used to create a 2D rack, which is a linear bar with teeth that a gear can roll along.
// A rack can mesh with any gear that has the same `pitch` and `pressure_angle`.
// When called as a function, returns a 2D path for the outline of the rack.
// When called as a module, creates a 2D rack shape.
// Arguments:
// pitch = The pitch, or distance in mm between teeth along the rack. Matches up with circular pitch on a spur gear. Default: 5
// teeth = Total number of teeth along the rack
// height = Height of rack in mm, from pitch line to back of rack.
2022-04-09 01:06:14 +00:00
// ---
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees.
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
// helical = The angle of the rack teeth away from perpendicular to the rack length. Stretches out the tooth shapes. Used to match helical spur gear pinions. Default: 0
2023-07-19 09:52:10 +00:00
// profile_shift = Profile shift factor x for tooth shape.
// gear_travel = The distance the rack should be moved by linearly. Default: 0
// rounding = If true, rack tips and valleys are slightly rounded. Default: true
// 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.
2021-11-20 03:33:16 +00:00
// 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`
// Extra Anchors:
// "adendum" = At the tips of the teeth, at the center of rack.
// "adendum-left" = At the tips of the teeth, at the left end of the rack.
// "adendum-right" = At the tips of the teeth, at the right end of the rack.
// "dedendum" = At the height of the teeth, at the center of rack.
// "dedendum-left" = At the height of the teeth, at the left end of the rack.
// "dedendum-right" = At the height of the teeth, at the right end of the rack.
// Example(2D):
// rack2d(pitch=5, teeth=10, height=10, pressure_angle=20);
// Example(2D): Called as a Function
// path = rack2d(pitch=8, teeth=8, height=10, pressure_angle=20);
// polygon(path);
function rack2d(
pitch,
teeth,
height = 10,
pressure_angle,
backlash = 0,
clearance,
helical,
profile_shift = 0,
circ_pitch,
diam_pitch,
mod,
gear_travel = 0,
2023-07-19 09:52:10 +00:00
rounding = true,
anchor = CENTER,
spin = 0
) = let(
pitch = _inherit_gear_pitch("rack2d()",pitch, circ_pitch, diam_pitch, mod, warn=false),
PA = _inherit_gear_pa(pressure_angle),
2023-07-20 03:29:49 +00:00
helical = _inherit_gear_helical(helical)
)
assert(is_integer(teeth) && teeth>0)
assert(is_finite(height) && height>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_travel))
let(
adendum = _adendum(pitch, profile_shift),
2023-07-15 23:35:18 +00:00
dedendum = _dedendum(pitch, clearance, profile_shift)
)
assert(dedendum < height, "height= is not large enough.")
let(
trans_pitch = pitch / cos(helical),
trans_pa = atan(tan(PA)/cos(helical)),
tthick = trans_pitch/PI * (PI/2 + 2*profile_shift * tan(PA)) - backlash,
l = teeth * trans_pitch,
ax = ang_adj_to_opp(trans_pa, adendum),
dx = ang_adj_to_opp(trans_pa, dedendum),
2023-07-19 09:52:10 +00:00
clear = dedendum - adendum,
poff = tthick/2 - backlash,
tooth = [
[-trans_pitch/2, -dedendum],
2023-07-19 09:52:10 +00:00
if (rounding) each arc(n=4, r=clear, corner=[
[-trans_pitch/2, -dedendum],
2023-07-19 09:52:10 +00:00
[-poff-dx, -dedendum],
[-poff+ax, +adendum],
]) else [-poff-dx, -dedendum],
if (rounding) each arc(n=4, r=trans_pitch/16, corner=[
[-poff-dx, -dedendum],
[-poff+ax, +adendum],
[+poff-ax, +adendum],
]) else [-poff+ax, +adendum],
if (rounding) each arc(n=4, r=trans_pitch/16, corner=[
[-poff+ax, +adendum],
[+poff-ax, +adendum],
[+poff+dx, -dedendum],
]) else [+poff-ax, +adendum],
if (rounding) each arc(n=4, r=clear, corner=[
[+poff-ax, +adendum],
[+poff+dx, -dedendum],
[+trans_pitch/2, -dedendum],
2023-07-19 09:52:10 +00:00
]) else [+poff+dx, -dedendum],
[+trans_pitch/2, -dedendum],
],
path2 = [
for(m = xcopies(trans_pitch,n=teeth))
each apply(m,tooth)
],
path = right(gear_travel, p=[
[path2[0].x, -height],
each path2,
[last(path2).x, -height],
]),
size=[l,2*height],
anchors = [
named_anchor("adendum", [ 0, adendum,0], BACK),
named_anchor("adendum-left", [-l/2, adendum,0], LEFT),
named_anchor("adendum-right", [ l/2, adendum,0], RIGHT),
named_anchor("dedendum", [ 0,-dedendum,0], BACK),
named_anchor("dedendum-left", [-l/2,-dedendum,0], LEFT),
named_anchor("dedendum-right", [ l/2,-dedendum,0], RIGHT),
]
) reorient(anchor,spin, two_d=true, size=size, anchors=anchors, p=path);
module rack2d(
pitch,
teeth,
height = 10,
pressure_angle,
backlash = 0.0,
clearance,
helical,
profile_shift = 0,
gear_travel = 0,
circ_pitch,
diam_pitch,
mod,
anchor = CENTER,
spin = 0
) {
pitch = _inherit_gear_pitch("rack2d()",pitch, circ_pitch, diam_pitch, mod, warn=false);
PA = _inherit_gear_pa(pressure_angle);
helical = _inherit_gear_helical(helical);
checks =
assert(is_integer(teeth) && teeth>0)
assert(is_finite(height) && height>0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_finite(helical) && abs(helical)<90)
assert(is_finite(profile_shift) && abs(profile_shift)<1)
assert(is_finite(gear_travel));
trans_pitch = pitch / cos(helical);
a = _adendum(pitch, profile_shift);
d = _dedendum(pitch, clearance, profile_shift);
l = teeth * trans_pitch;
path = rack2d(
pitch = pitch,
teeth = teeth,
height = height,
pressure_angle = PA,
backlash = backlash,
clearance = clearance,
helical = helical,
profile_shift= profile_shift
);
size = [l, 2*height];
anchors = [
2021-09-16 22:32:12 +00:00
named_anchor("adendum", [ 0, a,0], BACK),
named_anchor("adendum-left", [-l/2, a,0], LEFT),
named_anchor("adendum-right", [ l/2, a,0], RIGHT),
named_anchor("dedendum", [ 0,-d,0], BACK),
named_anchor("dedendum-left", [-l/2,-d,0], LEFT),
named_anchor("dedendum-right", [ l/2,-d,0], RIGHT),
];
attachable(anchor,spin, two_d=true, size=size, anchors=anchors) {
right(gear_travel) polygon(path);
children();
}
}
2022-03-28 03:06:42 +00:00
// Function&Module: bevel_gear()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a straight or spiral bevel gear.
// SynTags: Geom, VNF
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
// Usage: As a Module
// bevel_gear(circ_pitch, teeth, face_width, [pitch_angle=]|[mate_teeth=], [shaft_diam=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [internal=]);
// bevel_gear(mod=, teeth=, face_width=, [pitch_angle=]|[mate_teeth=], [shaft_diam=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [internal=]);
2022-03-28 03:06:42 +00:00
// Usage: As a Function
// vnf = bevel_gear(circ_pitch, teeth, face_width, [pitch_angle=]|[mate_teeth=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [internal=]);
// vnf = bevel_gear(mod=, teeth=, face_width=, [pitch_angle=]|[mate_teeth=], [hide=], [pressure_angle=], [clearance=], [backlash=], [cutter_radius=], [spiral_angle=], [left_handed=], [slices=], [internal=]);
// Description:
2022-03-28 03:06:42 +00:00
// Creates a (potentially spiral) bevel gear. The module `bevel_gear()` gives a bevel gear, with
// reasonable defaults for all the parameters. Normally, you should just choose the first 4
2023-06-18 13:22:41 +00:00
// parameters, and let the rest be default values. In straight bevel gear sets, when each tooth
// engages it inpacts the corresponding tooth. The abrupt tooth engagement causes impact stress
// which makes them more prone to breakage. Spiral bevel gears have teeth formed along spirals so
// they engage more gradually, resulting in a less abrupt transfer of force, so they are quieter
// in operation and less likely to break.
// .
// The module `bevel_gear()` gives a gear in the XY plane, centered on the origin, with one tooth
// centered on the positive Y axis. The various functions below it take the same parameters, and
// return various measurements for the gear. The most important function is `mesh_radius()`, which tells
// how far apart to space gears that are meshing, and `outer_radius()`, which gives the size of the
// region filled by the gear. A gear has a "pitch circle", which is an invisible circle that cuts
// through the middle of each tooth (though not the exact center). In order for two gears to mesh,
// their pitch circles should just touch, if no profile shifting is done). So the distance between
// their centers should be `mesh_radius()` for one, plus `mesh_radius()` for the other, which gives
// the radii of their pitch circles and profile shifts. In order for two gears to mesh, they must
// have the same `circ_pitch` and `pressure_angle` parameters. `circ_pitch` gives the number of millimeters
// of arc around the pitch circle covered by one tooth and one space between teeth. The `pressure_angle`
// controls how flat or bulged the sides of the teeth are. Common values include 14.5 degrees and 20
// degrees, and occasionally 25. The default here is 20 degrees. Larger numbers bulge out more,
// giving stronger teeth. The ratio of `teeth` for two meshing gears gives how many times one will make a full
// revolution when the the other makes one full revolution. If the two numbers are coprime (i.e.
// are not both divisible by the same number greater than 1), then every tooth on one gear will meet
// every tooth on the other, for more even wear. So coprime numbers of teeth are good.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm. Default: 5
2022-03-28 03:06:42 +00:00
// teeth = Total number of teeth around the entire perimeter. Default: 20
// face_width = Width of the toothed surface in mm, from inside to outside. Default: 10
// ---
2022-03-28 03:06:42 +00:00
// pitch_angle = Angle of beveled gear face. Default: 45
// mate_teeth = The number of teeth in the gear that this gear will mate with. Overrides `pitch_angle` if given.
// shaft_diam = Diameter of the hole in the center, in mm. Module use only. Default: 0 (no shaft hole)
// hide = Number of teeth to delete to make this only a fraction of a circle. Default: 0
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 20
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
2022-03-28 03:06:42 +00:00
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle. Default: 0
// cutter_radius = Radius of spiral arc for teeth. If 0, then gear will not be spiral. Default: 0
// spiral_angle = The base angle for spiral teeth. Default: 0
// left_handed = If true, the gear returned will have a left-handed spiral. Default: false
// slices = Number of vertical layers to divide gear into. Useful for refining gears with `spiral`. Default: 1
// internal = If true, create a mask for difference()ing from something else.
// 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.
2021-11-20 03:33:16 +00:00
// 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`
2022-03-28 03:06:42 +00:00
// Extra Anchors:
// "apex" = At the pitch cone apex for the bevel gear.
// "pitchbase" = At the natural height of the pitch radius of the beveled gear.
// "flattop" = At the top of the flat top of the bevel gear.
// Side Effects:
// If internal is true then the default tag is "remove"
2022-03-28 03:06:42 +00:00
// Example: Beveled Gear
// bevel_gear(
// circ_pitch=5, teeth=36, face_width=10, shaft_diam=5,
2022-03-28 03:06:42 +00:00
// pitch_angle=45, spiral_angle=0
// );
2022-03-28 03:06:42 +00:00
// Example: Spiral Beveled Gear and Pinion
// t1 = 16; t2 = 28;
// bevel_gear(
// circ_pitch=5, teeth=t1, mate_teeth=t2,
2022-03-28 03:06:42 +00:00
// slices=12, anchor="apex", orient=FWD
// );
// bevel_gear(
// circ_pitch=5, teeth=t2, mate_teeth=t1, left_handed=true,
2022-03-28 03:06:42 +00:00
// slices=12, anchor="apex", spin=180/t2
// );
// Example(Anim,Frames=4,VPD=175): Manual Spacing of Pinion and Gear
// t1 = 14; t2 = 28; circ_pitch=5;
// back(pitch_radius(circ_pitch, t2)) {
2022-03-28 03:06:42 +00:00
// yrot($t*360/t1)
// bevel_gear(
// circ_pitch=circ_pitch, teeth=t1, mate_teeth=t2, shaft_diam=5,
2022-03-28 03:06:42 +00:00
// slices=12, orient=FWD
// );
// }
// down(pitch_radius(circ_pitch, t1)) {
2022-03-28 03:06:42 +00:00
// zrot($t*360/t2)
// bevel_gear(
// circ_pitch=circ_pitch, teeth=t2, mate_teeth=t1, left_handed=true,
2022-03-28 03:06:42 +00:00
// shaft_diam=5, slices=12, spin=180/t2
// );
// }
2022-03-28 03:06:42 +00:00
function bevel_gear(
circ_pitch,
teeth,
2022-03-28 03:06:42 +00:00
face_width = 10,
pitch_angle = 45,
mate_teeth,
hide = 0,
2022-03-28 03:06:42 +00:00
pressure_angle = 20,
clearance,
backlash = 0.0,
2022-03-28 03:06:42 +00:00
cutter_radius = 30,
spiral_angle = 35,
left_handed = false,
slices = 5,
internal,
interior,
pitch,
diam_pitch,
mod,
2022-03-28 03:06:42 +00:00
anchor = "pitchbase",
spin = 0,
orient = UP
) = let(
dummy = !is_undef(interior) ? echo("In bevel_gear(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0,
internal = first_defined([internal,interior,false]),
circ_pitch = _inherit_gear_pitch("bevel_gear()",pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle),
spiral_angle = _inherit_gear_helical(spiral_angle, invert=!internal),
face_width = _inherit_gear_thickness(face_width),
2022-03-28 03:06:42 +00:00
slices = cutter_radius==0? 1 : slices,
pitch_angle = is_undef(mate_teeth)? pitch_angle : atan(teeth/mate_teeth),
pr = pitch_radius(circ_pitch, teeth),
rr = _root_radius(circ_pitch, teeth, clearance, internal),
2022-03-28 03:06:42 +00:00
pitchoff = (pr-rr) * sin(pitch_angle),
ocone_rad = opp_ang_to_hyp(pr, pitch_angle),
icone_rad = ocone_rad - face_width,
cutter_radius = cutter_radius==0? 1000 : cutter_radius,
midpr = (icone_rad + ocone_rad) / 2,
radcp = [0, midpr] + polar_to_xy(cutter_radius, 180+spiral_angle),
angC1 = law_of_cosines(a=cutter_radius, b=norm(radcp), c=ocone_rad),
angC2 = law_of_cosines(a=cutter_radius, b=norm(radcp), c=icone_rad),
radcpang = v_theta(radcp),
sang = radcpang - (180-angC1),
eang = radcpang - (180-angC2),
profile = reverse(_gear_tooth_profile(
circ_pitch = circ_pitch,
2022-03-28 03:06:42 +00:00
teeth = teeth,
pressure_angle = PA,
2022-03-28 03:06:42 +00:00
clearance = clearance,
backlash = backlash,
internal = internal,
2022-03-28 03:06:42 +00:00
center = true
)),
2022-03-28 03:06:42 +00:00
verts1 = [
for (v = lerpn(0,1,slices+1)) let(
p = radcp + polar_to_xy(cutter_radius, lerp(sang,eang,v)),
ang = v_theta(p)-90,
dist = norm(p)
) [
let(
u = dist / ocone_rad,
m = up((1-u) * pr / tan(pitch_angle)) *
up(pitchoff) *
zrot(ang/sin(pitch_angle)) *
back(u * pr) *
xrot(pitch_angle) *
scale(u)
)
for (tooth=[0:1:teeth-1])
each apply(xflip() * zrot(360*tooth/teeth) * m, path3d(profile))
]
],
2022-03-28 03:06:42 +00:00
botz = verts1[0][0].z,
topz = last(verts1)[0].z,
thickness = abs(topz - botz),
cpz = (topz + botz) / 2,
vertices = [for (x=verts1) reverse(x)],
sides_vnf = vnf_vertex_array(vertices, caps=false, col_wrap=true, reverse=true),
top_verts = last(vertices),
bot_verts = vertices[0],
gear_pts = len(top_verts),
face_pts = gear_pts / teeth,
top_faces =[
for (i=[0:1:teeth-1], j=[0:1:(face_pts/2)-1]) each [
[i*face_pts+j, (i+1)*face_pts-j-1, (i+1)*face_pts-j-2],
[i*face_pts+j, (i+1)*face_pts-j-2, i*face_pts+j+1]
],
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]
]
],
vnf1 = vnf_join([
[
[each top_verts, [0,0,top_verts[0].z]],
top_faces
],
[
[each bot_verts, [0,0,bot_verts[0].z]],
[for (x=top_faces) reverse(x)]
],
sides_vnf
]),
lvnf = left_handed? vnf1 : xflip(p=vnf1),
vnf = down(cpz, p=lvnf),
anchors = [
named_anchor("pitchbase", [0,0,pitchoff-thickness/2]),
named_anchor("flattop", [0,0,thickness/2]),
named_anchor("apex", [0,0,hyp_ang_to_opp(ocone_rad,90-pitch_angle)+pitchoff-thickness/2])
]
) reorient(anchor,spin,orient, vnf=vnf, extent=true, anchors=anchors, p=vnf);
2022-03-28 03:06:42 +00:00
module bevel_gear(
circ_pitch,
teeth,
2022-03-28 03:06:42 +00:00
face_width = 10,
pitch_angle = 45,
mate_teeth,
2020-10-21 05:24:12 +00:00
shaft_diam = 0,
2022-03-28 03:06:42 +00:00
pressure_angle = 20,
clearance = undef,
backlash = 0.0,
2022-03-28 03:06:42 +00:00
cutter_radius = 30,
spiral_angle = 35,
left_handed = false,
slices = 5,
internal,
interior,
pitch,
diam_pitch,
mod,
2022-03-28 03:06:42 +00:00
anchor = "pitchbase",
spin = 0,
orient = UP
) {
dummy = !is_undef(interior) ? echo("In bevel_gear(), the argument 'interior=' has been deprecated, and may be removed in the future. Please use 'internal=' instead."):0;
internal = first_defined([internal,interior,false]);
circ_pitch = _inherit_gear_pitch("bevel_gear()",pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
spiral_angle = _inherit_gear_helical(spiral_angle, invert=!internal);
face_width = _inherit_gear_thickness(face_width);
2022-03-28 03:06:42 +00:00
slices = cutter_radius==0? 1 : slices;
pitch_angle = is_undef(mate_teeth)? pitch_angle : atan(teeth/mate_teeth);
pr = pitch_radius(circ_pitch, teeth);
2022-03-28 03:06:42 +00:00
ipr = pr - face_width*sin(pitch_angle);
rr = _root_radius(circ_pitch, teeth, clearance, internal);
2022-03-28 03:06:42 +00:00
pitchoff = (pr-rr) * sin(pitch_angle);
vnf = bevel_gear(
circ_pitch = circ_pitch,
2022-03-28 03:06:42 +00:00
teeth = teeth,
face_width = face_width,
pitch_angle = pitch_angle,
pressure_angle = PA,
2022-03-28 03:06:42 +00:00
clearance = clearance,
backlash = backlash,
cutter_radius = cutter_radius,
spiral_angle = spiral_angle,
left_handed = left_handed,
slices = slices,
internal = internal,
2022-03-28 03:06:42 +00:00
anchor=CENTER
);
axis_zs = [for (p=vnf[0]) if(norm(point2d(p)) < EPSILON) p.z];
thickness = max(axis_zs) - min(axis_zs);
anchors = [
named_anchor("pitchbase", [0,0,pitchoff-thickness/2]),
named_anchor("flattop", [0,0,thickness/2]),
named_anchor("apex", [0,0,adj_ang_to_opp(pr,90-pitch_angle)+pitchoff-thickness/2])
];
default_tag("remove",internal) {
attachable(anchor,spin,orient, r1=pr, r2=ipr, h=thickness, anchors=anchors) {
difference() {
vnf_polyhedron(vnf, convexity=teeth/2);
if (shaft_diam > 0) {
cylinder(h=2*thickness+1, r=shaft_diam/2, center=true, $fn=max(12,segs(shaft_diam/2)));
}
}
children();
}
}
2019-06-12 02:29:39 +00:00
}
2022-03-28 03:06:42 +00:00
// Function&Module: worm()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a worm that will mate with a worm gear.
// SynTags: Geom, VNF
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
// Usage: As a Module
// worm(circ_pitch, d, l, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// worm(mod=, d=, l=, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// Usage: As a Function
// vnf = worm(circ_pitch, d, l, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
// vnf = worm(mod=, d=, l=, [starts=], [left_handed=], [pressure_angle=], [backlash=], [clearance=]);
2019-06-12 02:29:39 +00:00
// Description:
2022-03-28 03:06:42 +00:00
// Creates a worm shape that can be matched to a worm gear.
2019-06-12 02:29:39 +00:00
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm. Default: 5
2022-03-28 03:06:42 +00:00
// d = The diameter of the worm. Default: 30
// l = The length of the worm. Default: 100
// starts = The number of lead starts. Default: 1
2020-10-21 05:24:12 +00:00
// left_handed = If true, the gear returned will have a left-handed spiral. Default: false
2022-03-28 03:06:42 +00:00
// 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
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
// profile_shift = Profile shift factor x.
// 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.
2021-11-20 03:33:16 +00:00
// 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`
2022-03-28 03:06:42 +00:00
// Example:
// worm(circ_pitch=8, d=30, l=50, $fn=72);
2022-03-28 03:06:42 +00:00
// Example: Multiple Starts.
// worm(circ_pitch=8, d=30, l=50, starts=3, $fn=72);
2022-03-28 03:06:42 +00:00
// Example: Left Handed
// worm(circ_pitch=8, d=30, l=50, starts=3, left_handed=true, $fn=72);
2022-03-28 03:06:42 +00:00
// Example: Called as Function
// vnf = worm(circ_pitch=8, d=35, l=50, starts=2, left_handed=true, pressure_angle=20, $fn=72);
2022-03-28 03:06:42 +00:00
// vnf_polyhedron(vnf);
2022-03-28 03:06:42 +00:00
function worm(
circ_pitch,
2022-03-28 03:06:42 +00:00
d=30, l=100,
starts=1,
left_handed=false,
pressure_angle,
2022-03-28 03:06:42 +00:00
backlash=0,
clearance,
profile_shift,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
pitch,
2023-07-21 08:04:02 +00:00
gear_spin=0,
2022-03-28 03:06:42 +00:00
anchor=CENTER,
spin=0,
orient=UP
) =
let(
circ_pitch = _inherit_gear_pitch("worm()", pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle),
2023-07-20 04:06:33 +00:00
profile_shift = default(profile_shift, 0)
)
assert(is_integer(starts) && starts>0)
assert(is_finite(l) && l>0)
//assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_bool(left_handed))
assert(is_finite(profile_shift) && abs(profile_shift)<1)
2023-07-21 08:04:02 +00:00
assert(is_finite(gear_spin))
let(
helical = asin(starts * circ_pitch / PI / d),
trans_pitch = circ_pitch / cos(helical),
tooth = xflip(
p=select(rack2d(
pitch=circ_pitch,
teeth=1,
pressure_angle=PA,
clearance=clearance,
backlash=backlash,
helical=helical,
profile_shift=profile_shift
), 1, -2)
),
rack_profile = [
for (t = xcopies(trans_pitch, n=2*ceil(l/trans_pitch)+1))
each apply(t, tooth)
2022-03-28 03:06:42 +00:00
],
steps = max(36, segs(d/2)),
step = 360 / steps,
2023-07-21 08:04:02 +00:00
zsteps = ceil(l / trans_pitch / starts * steps),
zstep = l / zsteps,
2022-03-28 03:06:42 +00:00
profiles = [
for (j = [0:1:zsteps]) [
for (i = [0:1:steps-1]) let(
u = i / steps - 0.5,
ang = 360 * (1 - u) + 90,
z = j*zstep - l/2,
2023-07-21 08:04:02 +00:00
zoff = trans_pitch * starts * u,
h = lookup(z+zoff, rack_profile)
)
cylindrical_to_xyz(d/2+h, ang, z)
]
2022-03-28 03:06:42 +00:00
],
vnf1 = vnf_vertex_array(profiles, caps=true, col_wrap=true, style="alt"),
2023-07-21 08:04:02 +00:00
m = product([
zrot(gear_spin),
if (left_handed) xflip(),
]),
vnf = apply(m, vnf1)
2022-03-28 03:06:42 +00:00
) reorient(anchor,spin,orient, d=d, l=l, p=vnf);
module worm(
circ_pitch,
2022-03-28 03:06:42 +00:00
d=15, l=100,
starts=1,
left_handed=false,
pressure_angle,
2022-03-28 03:06:42 +00:00
backlash=0,
clearance,
profile_shift=0,
pitch,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
gear_spin=0,
2022-03-28 03:06:42 +00:00
anchor=CENTER,
spin=0,
orient=UP
) {
circ_pitch = _inherit_gear_pitch("worm()", pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
profile_shift = default(profile_shift, auto_profile_shift(starts,PA));
checks =
assert(is_integer(starts) && starts>0)
assert(is_finite(l) && l>0)
//assert(is_finite(shaft_diam) && shaft_diam>=0)
assert(is_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
assert(is_bool(left_handed))
assert(is_finite(gear_spin))
assert(is_finite(profile_shift) && abs(profile_shift)<1);
2023-07-21 08:04:02 +00:00
helical = asin(starts * circ_pitch / PI / d);
trans_pitch = circ_pitch / cos(helical);
2022-03-28 03:06:42 +00:00
vnf = worm(
circ_pitch=circ_pitch,
2022-03-28 03:06:42 +00:00
starts=starts,
d=d, l=l,
left_handed=left_handed,
pressure_angle=PA,
2022-03-28 03:06:42 +00:00
backlash=backlash,
clearance=clearance,
profile_shift=profile_shift,
2022-03-28 03:06:42 +00:00
mod=mod
);
attachable(anchor,spin,orient, d=d, l=l) {
2023-07-21 08:04:02 +00:00
zrot(gear_spin) vnf_polyhedron(vnf, convexity=ceil(l/trans_pitch)*2);
2022-03-28 03:06:42 +00:00
children();
}
}
// Function&Module: worm_gear()
2023-06-18 13:22:41 +00:00
// Synopsis: Creates a worm gear that will mate with a worm.
// SynTags: Geom, VNF
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), rack(), rack2d(), spur_gear(), spur_gear2d(), bevel_pitch_angle(), bevel_gear()
2022-03-28 03:06:42 +00:00
// Usage: As a Module
// worm_gear(circ_pitch, teeth, worm_diam, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=], [shaft_diam=]) [ATTACHMENTS];
// worm_gear(mod=, teeth=, worm_diam=, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=], [shaft_diam=]) [ATTACHMENTS];
2022-03-28 03:06:42 +00:00
// Usage: As a Function
// vnf = worm_gear(circ_pitch, teeth, worm_diam, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=]);
// vnf = worm_gear(mod=, teeth=, worm_diam=, [worm_starts=], [worm_arc=], [crowning=], [left_handed=], [pressure_angle=], [backlash=], [clearance=], [slices=]);
2022-03-28 03:06:42 +00:00
// Description:
// Creates a worm gear to match with a worm.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm. Default: 5
2022-03-28 03:06:42 +00:00
// teeth = Total number of teeth along the rack. Default: 30
// worm_diam = The pitch diameter of the worm gear to match to. Default: 30
// worm_starts = The number of lead starts on the worm gear to match to. Default: 1
// worm_arc = The arc of the worm to mate with, in degrees. Default: 60 degrees
2023-06-18 13:22:41 +00:00
// crowning = The amount to oversize the virtual hobbing cutter used to make the teeth, to add a slight crowning to the teeth to make them fit the work easier. Default: 1
2022-03-28 03:06:42 +00:00
// left_handed = If true, the gear returned will have a left-handed spiral. Default: false
// 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
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
// profile_shift = Profile shift factor x.
2022-03-28 03:06:42 +00:00
// slices = The number of vertical slices to refine the curve of the worm throat. Default: 10
// 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.
2022-03-28 03:06:42 +00:00
// 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: Right-Handed
// worm_gear(circ_pitch=5, teeth=36, worm_diam=30, worm_starts=1);
2022-03-28 03:06:42 +00:00
// Example: Left-Handed
// worm_gear(circ_pitch=5, teeth=36, worm_diam=30, worm_starts=1, left_handed=true);
2022-03-28 03:06:42 +00:00
// Example: Multiple Starts
// worm_gear(circ_pitch=5, teeth=36, worm_diam=30, worm_starts=4);
2022-03-28 03:06:42 +00:00
// Example: Metric Worm Gear
// worm_gear(mod=2, teeth=32, worm_diam=30, worm_starts=1);
// Example(Anim,Frames=4,FrameMS=125,VPD=220,VPT=[-15,0,0]): Meshing Worm and Gear
// $fn=36;
// circ_pitch = 5; starts = 4;
2022-03-28 03:06:42 +00:00
// worm_diam = 30; worm_length = 50;
// gear_teeth=36;
// right(worm_diam/2)
// yrot($t*360/starts)
// worm(
// d=worm_diam,
// l=worm_length,
// circ_pitch=circ_pitch,
// starts=starts,
// orient=BACK);
// left(pitch_radius(circ_pitch, gear_teeth))
2022-03-28 03:06:42 +00:00
// zrot(-$t*360/gear_teeth)
// worm_gear(
// circ_pitch=circ_pitch,
// teeth=gear_teeth,
// worm_diam=worm_diam,
// worm_starts=starts);
2022-03-28 03:06:42 +00:00
// Example: Meshing Worm and Gear Metricly
// $fn = 72;
// modulus = 2; starts = 3;
// worm_diam = 30; worm_length = 50;
// gear_teeth=36;
// right(worm_diam/2)
// worm(d=worm_diam, l=worm_length, mod=modulus, starts=starts, orient=BACK);
// left(pitch_radius(mod=modulus, teeth=gear_teeth))
// worm_gear(mod=modulus, teeth=gear_teeth, worm_diam=worm_diam, worm_starts=starts);
// Example: Called as Function
// vnf = worm_gear(circ_pitch=8, teeth=30, worm_diam=30, worm_starts=1);
2022-03-28 03:06:42 +00:00
// vnf_polyhedron(vnf);
2022-03-28 03:06:42 +00:00
function worm_gear(
circ_pitch,
teeth,
worm_diam,
2022-03-28 03:06:42 +00:00
worm_starts = 1,
worm_arc = 60,
crowning = 0.1,
left_handed = false,
pressure_angle,
2022-03-28 03:06:42 +00:00
backlash = 0,
clearance,
profile_shift,
2022-03-28 03:06:42 +00:00
slices = 10,
gear_spin=0,
pitch,
diam_pitch,
mod,
2022-03-28 03:06:42 +00:00
anchor = CENTER,
spin = 0,
orient = UP
) =
2022-03-28 03:06:42 +00:00
assert(worm_arc >= 10 && worm_arc <= 60)
let(
circ_pitch = _inherit_gear_pitch("worm_gear()", pitch, circ_pitch, diam_pitch, mod),
PA = _inherit_gear_pa(pressure_angle),
2023-07-20 04:06:33 +00:00
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA))
)
assert(is_integer(teeth) && teeth>10)
assert(is_finite(worm_diam) && worm_diam>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_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
//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(
helical = asin(worm_starts * circ_pitch / PI / worm_diam),
pr = pitch_radius(circ_pitch, teeth, helical),
hob_rad = worm_diam / 2 + crowning,
thickness = worm_gear_thickness(circ_pitch=circ_pitch, teeth=teeth, worm_diam=worm_diam, worm_arc=worm_arc, crowning=crowning, clearance=clearance),
tooth_profile = _gear_tooth_profile(
circ_pitch=circ_pitch,
teeth=teeth,
pressure_angle=PA,
clearance=clearance,
backlash=backlash,
helical=helical,
profile_shift=profile_shift,
center=true
),
tbot = min(column(tooth_profile,1)),
arcthick = hob_rad * sin(worm_arc/2) * 2,
twist = sin(helical)*arcthick / (2*PI*pr) * 360,
2022-03-28 03:06:42 +00:00
profiles = [
for (slice = [0:1:slices]) let(
u = slice/slices - 0.5
2021-04-19 21:55:50 +00:00
) [
2022-03-28 03:06:42 +00:00
for (i = [0:1:teeth-1]) each
apply(
zrot(-i*360/teeth + twist*u - 0.5) *
right(pr+hob_rad) *
yrot(u*worm_arc) *
left(hob_rad) *
zrot(-90) *
back(tbot) *
2023-07-21 08:04:02 +00:00
scale(pow(cos(u*worm_arc),2)) *
fwd(tbot),
2022-03-28 03:06:42 +00:00
path3d(tooth_profile)
)
]
],
2022-03-28 03:06:42 +00:00
top_verts = last(profiles),
bot_verts = profiles[0],
face_pts = len(tooth_profile),
gear_pts = face_pts * teeth,
top_faces =[
2022-03-28 03:06:42 +00:00
for (i=[0:1:teeth-1], j=[0:1:(face_pts/2)-2]) each [
[i*face_pts+j, (i+1)*face_pts-j-1, (i+1)*face_pts-j-2],
[i*face_pts+j, (i+1)*face_pts-j-2, i*face_pts+j+1]
],
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]
]
],
2022-03-28 03:06:42 +00:00
sides_vnf = vnf_vertex_array(profiles, caps=false, col_wrap=true, style="min_edge"),
2021-11-11 13:45:30 +00:00
vnf1 = vnf_join([
[
[each top_verts, [0,0,top_verts[0].z]],
2022-03-28 03:06:42 +00:00
[for (x=top_faces) reverse(x)]
],
[
[each bot_verts, [0,0,bot_verts[0].z]],
2022-03-28 03:06:42 +00:00
top_faces
],
sides_vnf
]),
m = product([
zrot(gear_spin),
if (left_handed) xflip(),
]),
vnf = apply(m,vnf1)
) reorient(anchor,spin,orient, r=pr, l=thickness, p=vnf);
2022-03-28 03:06:42 +00:00
module worm_gear(
circ_pitch,
teeth,
worm_diam,
2022-03-28 03:06:42 +00:00
worm_starts = 1,
worm_arc = 60,
crowning = 0.1,
2022-03-28 03:06:42 +00:00
left_handed = false,
pressure_angle,
clearance,
2022-03-28 03:06:42 +00:00
backlash = 0,
shaft_diam = 0,
2022-03-28 03:06:42 +00:00
slices = 10,
profile_shift,
gear_spin=0,
pitch,
diam_pitch,
2022-03-28 03:06:42 +00:00
mod,
anchor = CENTER,
spin = 0,
orient = UP
) {
circ_pitch = _inherit_gear_pitch("worm_gear()", pitch, circ_pitch, diam_pitch, mod);
PA = _inherit_gear_pa(pressure_angle);
profile_shift = default(profile_shift, auto_profile_shift(teeth,PA));
checks =
assert(is_integer(teeth) && teeth>10)
assert(is_finite(worm_diam) && worm_diam>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_finite(PA) && PA>=0 && PA<90, "Bad pressure_angle value.")
assert(clearance==undef || (is_finite(clearance) && clearance>=0))
assert(is_finite(backlash) && backlash>=0)
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));
helical = asin(worm_starts * circ_pitch / PI / worm_diam);
pr = pitch_radius(circ_pitch, teeth, helical);
2022-03-28 03:06:42 +00:00
vnf = worm_gear(
circ_pitch = circ_pitch,
2022-03-28 03:06:42 +00:00
teeth = teeth,
worm_diam = worm_diam,
worm_starts = worm_starts,
worm_arc = worm_arc,
crowning = crowning,
left_handed = left_handed,
pressure_angle = PA,
2022-03-28 03:06:42 +00:00
backlash = backlash,
clearance = clearance,
profile_shift = profile_shift,
slices = slices
2022-03-28 03:06:42 +00:00
);
thickness = pointlist_bounds(vnf[0])[1].z;
attachable(anchor,spin,orient, r=pr, l=thickness) {
zrot(gear_spin)
2022-03-28 03:06:42 +00:00
difference() {
vnf_polyhedron(vnf, convexity=teeth/2);
if (shaft_diam > 0) {
cylinder(h=2*thickness+1, r=shaft_diam/2, center=true, $fn=max(12,segs(shaft_diam/2)));
2022-03-28 03:06:42 +00:00
}
}
children();
}
}
/// Function: _gear_tooth_profile()
/// Usage: As Function
/// path = _gear_tooth_profile(pitch, teeth, [pressure_angle], [clearance], [backlash], [internal]);
/// Topics: Gears
/// See Also: spur_gear2d()
/// Description:
/// When called as a function, returns the 2D profile path for an individual gear tooth.
/// When called as a module, creates the 2D profile shape for an individual gear tooth.
/// Arguments:
/// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
/// teeth = Total number of teeth on the spur gear that this is a tooth for.
/// pressure_angle = Pressure Angle. Controls how straight or bulged the tooth sides are. In degrees.
/// clearance = Gap between top of a tooth on one gear and bottom of valley on a meshing gear (in millimeters)
/// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle
/// internal = If true, create a mask for difference()ing from something else.
/// center = If true, centers the pitch circle of the tooth profile at the origin. Default: false.
/// 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.
/// Example(2D):
/// _gear_tooth_profile(circ_pitch=5, teeth=20, pressure_angle=20);
/// Example(2D): Metric Gear Tooth
/// _gear_tooth_profile(mod=2, teeth=20, pressure_angle=20);
/// Example(2D):
/// _gear_tooth_profile(
/// circ_pitch=5, teeth=20, pressure_angle=20
/// );
/// Example(2D): As a function
/// path = _gear_tooth_profile(
/// circ_pitch=5, teeth=20, pressure_angle=20
/// );
/// stroke(path, width=0.1);
function _gear_tooth_profile(
circ_pitch,
teeth,
pressure_angle = 20,
clearance,
2022-03-28 03:06:42 +00:00
backlash = 0.0,
helical = 0,
internal = false,
profile_shift = 0.0,
2023-07-21 07:05:53 +00:00
mod,
diam_pitch,
pitch,
center = false
2022-03-28 03:06:42 +00:00
) = let(
// Calculate a point on the involute curve, by angle.
_involute = function(base_r,a)
let(b=a*PI/180) base_r * [cos(a)+b*sin(a), sin(a)-b*cos(a)],
steps = 16,
2023-07-21 07:05:53 +00:00
circ_pitch = circular_pitch(pitch=pitch, circ_pitch=circ_pitch, diam_pitch=diam_pitch, mod=mod),
// Calculate the important circle radii
arad = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=internal),
prad = pitch_radius(circ_pitch, teeth, helical=helical),
brad = _base_radius(circ_pitch, teeth, pressure_angle, helical=helical),
rrad = _root_radius(circ_pitch, teeth, clearance, helical=helical, profile_shift=profile_shift, internal=internal),
srad = max(rrad,brad),
clear = default(clearance, circ_pitch/PI * 0.25),
tthick = circ_pitch/PI / cos(helical) * (PI/2 + 2*profile_shift * tan(pressure_angle)) - backlash,
tang = tthick / prad / 2 * 180 / PI,
// Generate a lookup table for the involute curve angles, by radius
involute_lup = [
if (rrad < brad)
each xy_to_polar(arc(n=4, r=min(brad-rrad,clear), corner=[
polar_to_xy(rrad,90+180/teeth),
polar_to_xy(rrad,90),
polar_to_xy(brad,90),
])),
for (i=[0:5:arad/PI/brad*360])
let(
xy = _involute(brad,i),
pol = xy_to_polar(xy)
)
if (pol.x <= arad * 1.1)
[pol.x, 90-pol.y]
2022-03-28 03:06:42 +00:00
],
// Generate reverse lookup table for involute radii, by angle
involute_rlup = mirror([-1,1],p=involute_lup), // swaps X and Y columns.
a_ang = lookup(arad, involute_lup),
p_ang = lookup(prad, involute_lup),
b_ang = lookup(brad, involute_lup),
r_ang = lookup(rrad, involute_lup),
s_ang = lookup(srad, involute_lup),
soff = tang + (b_ang - p_ang),
ma_rad = min(arad, lookup(90-soff+0.05*360/teeth/2, involute_rlup)),
ma_ang = lookup(ma_rad, involute_lup),
cap_steps = ceil((ma_ang + soff - 90) / 5),
cap_step = (ma_ang + soff - 90) / cap_steps,
ax = circ_pitch/4 - ang_adj_to_opp(pressure_angle, circ_pitch/PI),
// Calculate the undercut a meshing rack might carve out of this tooth.
undercut = [
for (a=[atan2(ax,rrad):-1:-90])
let(
bx = -a/360 * 2*PI*prad,
x = bx + ax,
y = prad - circ_pitch/PI + profile_shift*circ_pitch/PI,
pol = xy_to_polar(x,y)
)
if (pol.x < arad*1.05)
[pol.x, pol.y-a+180/teeth]
],
uc_min = min_index(column(undercut,0)),
// Generate a fast lookup table for the undercut.
undercut_lup = [for (i=idx(undercut)) if (i>=uc_min) undercut[i]],
// The u values to use when generating the tooth.
us = [
2023-07-21 07:05:53 +00:00
for (i=[0.0:0.02:0.2-EPSILON]) i,
for (i=[0:1:steps-1]) 0.2 + i/(steps-1)*0.8,
],
// Generate the left half of the tooth.
tooth_half_raw = deduplicate([
for (u = us) let(
r = lerp(rrad, ma_rad, u),
a1 = lookup(r, involute_lup) + soff,
a2 = lookup(r, undercut_lup),
a = internal || r < undercut_lup[0].x? a1 : min(a1,a2)
) if(a<90+180/teeth) polar_to_xy(r, a),
for (i=[0:1:cap_steps-1]) let(
a = ma_ang + soff - i * (cap_step-1)
) polar_to_xy(ma_rad, a),
]),
// Strip "jaggies" if found.
2023-07-21 07:05:53 +00:00
strip_left = function(path,i)
i > len(path)? [] :
norm(path[i]) >= prad? [for (j=idx(path)) if(j>=i) path[j]] :
let(
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.
tooth = deduplicate([
each tooth_half,
each reverse(xflip(tooth_half)),
]),
out = center? fwd(prad, p=tooth) : tooth
) out;
2022-03-28 03:06:42 +00:00
// Section: Computing Gear Dimensions
// These functions let the user find the derived dimensions of the gear.
// A gear fits within a circle of radius outer_radius, and two gears should have
// their centers separated by the sum of their pitch_radius.
// Function: circular_pitch()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns tooth density expressed as "circular pitch".
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
2022-03-28 03:06:42 +00:00
// Usage:
// circ_pitch = circular_pitch(circ_pitch);
// circ_pitch = circular_pitch(mod=);
// circ_pitch = circular_pitch(diam_pitch=);
// Description:
// Get tooth density expressed as "circular pitch", or the distance in mm between teeth around the pitch circle.
// For example, if you have a gear with 11 teeth, and the pitch diameter is 35mm, then the circumfrence
// of the pitch diameter is really close to 110mm, making the circular pitch of that gear about 10mm/tooth.
// Arguments:
// circ_pitch = The circular pitch, or distance in mm between teeth around the pitch circle.
// ---
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
// Example(VPT=[0,31,0];VPR=[0,0,0];VPD=40):
// $fn=144;
// teeth=20;
// circ_pitch = circular_pitch(diam_pitch=8);
// pr = pitch_radius(circ_pitch, teeth);
// stroke(spur_gear2d(circ_pitch, teeth), width=0.1);
// color("cyan")
// dashed_stroke(circle(r=pr), width=0.1);
// color("black") {
// stroke(
// arc(r=pr, start=90+90/teeth, angle=-360/teeth),
// width=0.2, endcaps="arrow");
// back(pr+1) right(3)
// zrot(30) text("Circular Pitch", size=1);
// }
2022-03-28 03:06:42 +00:00
// Example:
// circ_pitch = circular_pitch(circ_pitch=5);
// circ_pitch = circular_pitch(diam_pitch=12);
// circ_pitch = circular_pitch(mod=2);
function circular_pitch(circ_pitch, mod, pitch, diam_pitch) =
assert(one_defined([pitch, mod, circ_pitch, diam_pitch], "pitch,mod,circ_pitch,diam_pitch"))
pitch != undef? assert(is_finite(pitch) && pitch>0) pitch :
circ_pitch != undef? assert(is_finite(circ_pitch) && circ_pitch>0) circ_pitch :
diam_pitch != undef? assert(is_finite(diam_pitch) && diam_pitch>0) PI / diam_pitch * INCH :
assert(is_finite(mod) && mod>0) mod * PI;
2022-03-28 03:06:42 +00:00
// Function: diametral_pitch()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns tooth density expressed as "diametral pitch".
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
2022-03-28 03:06:42 +00:00
// Usage:
// dp = diametral_pitch(circ_pitch);
// dp = diametral_pitch(mod=);
// dp = diametral_pitch(diam_pitch=);
2022-03-28 03:06:42 +00:00
// Description:
// Returns tooth density expressed as "diametral pitch", the number of teeth per inch of pitch diameter.
// For example, if you have a gear with 30 teeth, with a 1.5 inch pitch diameter, then you have a
// diametral pitch of 20 teeth/inch.
2022-03-28 03:06:42 +00:00
// Arguments:
// circ_pitch = The circular pitch, or distance in mm between teeth around the pitch circle.
// ---
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
2022-03-28 03:06:42 +00:00
// Example:
// diam_pitch = diametral_pitch(mod=2);
// diam_pitch = diametral_pitch(circ_pitch=8);
// diam_pitch = diametral_pitch(diam_pitch=16);
function diametral_pitch(circ_pitch, mod, pitch, diam_pitch) =
let( circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch) )
PI / circ_pitch / INCH;
2022-03-28 03:06:42 +00:00
// Function: pitch_value()
// Synopsis: Returns tooth density expressed as "circular pitch".
2023-04-05 00:25:13 +00:00
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
2022-03-28 03:06:42 +00:00
// Usage:
// circ_pitch = pitch_value(mod);
// circ_pitch = pitch_value(circ_pitch=);
// circ_pitch = pitch_value(diam_pitch=);
2022-03-28 03:06:42 +00:00
// Description:
// Returns the circular pitch in mm from module/modulus or diametral pitch.
// The circular pitch of a gear is the number of millimeters per tooth around the pitch radius circle.
// For example, if you have a gear with 11 teeth, and the pitch diameter is 35mm, then the circumfrence
// of the pitch diameter is really close to 110mm, making the circular pitch of that gear about 10mm/tooth.
2022-03-28 03:06:42 +00:00
// Arguments:
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// ---
// circ_pitch = The circular pitch, or distance in mm between teeth around the pitch circle.
// 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.
// Example:
// circ_pitch = pitch_value(mod=2);
// circ_pitch = pitch_value(circ_pitch=8);
// circ_pitch = pitch_value(diam_pitch=16);
function pitch_value(mod, circ_pitch, diam_pitch) =
circular_pitch(mod=mod, circ_pitch=circ_pitch, diam_pitch=diam_pitch);
2022-03-28 03:06:42 +00:00
// Function: module_value()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns tooth density expressed as "module" or "modulus" in millimeters.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value()
2022-03-28 03:06:42 +00:00
// Usage:
// mod = module_value(circ_pitch);
// mod = module_value(mod=);
// mod = module_value(diam_pitch=);
2022-03-28 03:06:42 +00:00
// Description:
// Get tooth density expressed as "module" or "modulus" in millimeters. The module is the pitch
// diameter of the gear divided by the number of teeth on it. For example, a gear with a pitch
// diameter of 40mm, with 20 teeth on it will have a modulus of 2.
// Arguments:
// circ_pitch = The circular pitch, or distance in mm between teeth around the pitch circle.
// ---
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
// Example:
// mod = module_value(circ_pitch=8);
// mod = module_value(mod=2);
// mod = module_value(diam_pitch=16);
function module_value(circ_pitch, mod, pitch, diam_pitch) =
let( circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch) )
circ_pitch / PI;
2022-03-28 03:06:42 +00:00
/// Function: _adendum()
/// Usage:
/// ad = _adendum(circ_pitch, [profile_shift]);
/// ad = _adendum(diam_pitch=, [profile_shift=]);
/// ad = _adendum(mod=, [profile_shift=]);
/// Topics: Gears
/// Description:
/// The height of the top of a gear tooth above the pitch radius circle.
/// Arguments:
/// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
/// profile_shift = Profile shift factor x.
/// ---
/// 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.
/// Example:
/// ad = _adendum(circ_pitch=5);
/// ad = _adendum(mod=2);
/// Example(2D):
/// circ_pitch = 5; teeth = 17;
/// pr = pitch_radius(circ_pitch, teeth);
/// adn = _adendum(circ_pitch=5);
/// #spur_gear2d(circ_pitch=circ_pitch, teeth=teeth);
/// color("black") {
/// stroke(circle(r=pr),width=0.1,closed=true);
/// stroke(circle(r=pr+adn),width=0.1,closed=true);
/// }
function _adendum(
circ_pitch,
profile_shift=0,
diam_pitch,
mod,
pitch
) =
let( mod = module_value(circ_pitch, mod, pitch, diam_pitch) )
mod * (1 + profile_shift);
2017-08-30 00:00:16 +00:00
/// Function: _dedendum()
/// Usage:
/// ddn = _dedendum(circ_pitch=, [clearance], [profile_shift]);
/// ddn = _dedendum(diam_pitch=, [clearance=], [profile_shift=]);
/// ddn = _dedendum(mod=, [clearance=], [profile_shift=]);
/// Topics: Gears
/// Description:
/// The depth of the gear tooth valley, below the pitch radius.
/// Arguments:
/// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
/// clearance = If given, sets the clearance between meshing teeth.
/// profile_shift = Profile shift factor x.
/// ---
/// 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.
/// Example:
/// ddn = _dedendum(circ_pitch=5);
/// ddn = _dedendum(mod=2);
/// Example(2D):
/// circ_pitch = 5; teeth = 17;
/// pr = pitch_radius(circ_pitch, teeth);
/// ddn = _dedendum(circ_pitch=5);
/// #spur_gear2d(circ_pitch=circ_pitch, teeth=teeth);
/// color("black") {
/// stroke(circle(r=pr),width=0.1,closed=true);
/// stroke(circle(r=pr-ddn),width=0.1,closed=true);
/// }
function _dedendum(
circ_pitch,
clearance,
profile_shift=0,
diam_pitch,
mod,
pitch
) = let(
mod = module_value(circ_pitch, mod, pitch, diam_pitch),
clearance = default(clearance, 0.25 * mod)
)
mod * (1 - profile_shift) + clearance;
2022-03-28 03:06:42 +00:00
2022-03-28 03:06:42 +00:00
// Function: pitch_radius()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns the pitch radius for a gear.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value(), outer_radius()
2022-03-28 03:06:42 +00:00
// Usage:
// pr = pitch_radius(pitch, teeth, [helical]);
// pr = pitch_radius(mod=, teeth=, [helical=]);
2022-03-28 03:06:42 +00:00
// Description:
// Calculates the pitch radius for the gear. Two mated gears will have their centers spaced apart
// by the sum of the two gear's pitch radii.
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
2022-03-28 03:06:42 +00:00
// teeth = The number of teeth on the gear.
// helical = The helical angle (from vertical) of the teeth on the gear. Default: 0
// ---
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
2022-03-28 03:06:42 +00:00
// Example:
// pr = pitch_radius(circ_pitch=5, teeth=11);
// pr = pitch_radius(circ_pitch=5, teeth=11, helical=30);
// pr = pitch_radius(diam_pitch=10, teeth=11);
2022-03-28 03:06:42 +00:00
// pr = pitch_radius(mod=2, teeth=20);
// pr = pitch_radius(mod=2, teeth=20, helical=30);
2022-03-28 03:06:42 +00:00
// Example(2D):
// $fn=144;
// teeth=17; circ_pitch = 5;
// pr = pitch_radius(circ_pitch, teeth);
// stroke(spur_gear2d(circ_pitch, teeth), width=0.1);
// color("blue") dashed_stroke(circle(r=pr), width=0.1);
// color("black") {
// stroke([[0,0],polar_to_xy(pr,45)],
// endcaps="arrow", width=0.3);
// fwd(1)
// text("Pitch Radius", size=1.5,
// halign="center", valign="top");
// }
function pitch_radius(
circ_pitch,
teeth,
helical=0,
mod,
diam_pitch,
pitch
) =
let( circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch) )
circ_pitch * teeth / PI / 2 / cos(helical);
2022-03-28 03:06:42 +00:00
// Function: outer_radius()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns the outer radius for a gear.
// Topics: Gears, Parts
// See Also: spur_gear(), diametral_pitch(), circular_pitch(), pitch_value(), module_value(), pitch_radius(), outer_radius()
2022-03-28 03:06:42 +00:00
// Usage:
// or = outer_radius(circ_pitch, teeth, [helical=], [clearance=], [internal=], [profile_shift=]);
// or = outer_radius(mod=, teeth=, [helical=], [clearance=], [internal=], [profile_shift=]);
// or = outer_radius(diam_pitch=, teeth=, [helical=], [clearance=], [internal=], [profile_shift=]);
2020-10-21 05:24:12 +00:00
// Description:
2022-03-28 03:06:42 +00:00
// Calculates the outer radius for the gear. The gear fits entirely within a cylinder of this radius.
2020-10-21 05:24:12 +00:00
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
2022-03-28 03:06:42 +00:00
// teeth = The number of teeth on the gear.
// ---
2022-03-28 03:06:42 +00:00
// clearance = If given, sets the clearance between meshing teeth.
// profile_shift = Profile shift factor x.
// internal = If true, calculate for an internal gear.
// helical = The helical angle (from vertical) of the teeth on the gear. Default: 0
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
2020-10-21 05:24:12 +00:00
// Example:
// or = outer_radius(circ_pitch=5, teeth=20);
// or = outer_radius(circ_pitch=5, teeth=20, helical=30);
// or = outer_radius(diam_pitch=10, teeth=17);
2022-03-28 03:06:42 +00:00
// or = outer_radius(mod=2, teeth=16);
// Example(2D):
// $fn=144;
// teeth=17; circ_pitch = 5;
// or = outer_radius(circ_pitch, teeth);
// stroke(spur_gear2d(circ_pitch, teeth), width=0.1);
// color("blue") dashed_stroke(circle(r=or), width=0.1);
// color("black") {
// stroke([[0,0],polar_to_xy(or,45)],
// endcaps="arrow", width=0.3);
// fwd(1)
// text("Outer Radius", size=1.5,
// halign="center", valign="top");
// }
function outer_radius(circ_pitch, teeth, clearance, internal=false, helical=0, profile_shift=0, mod, pitch, diam_pitch) =
let( circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch) )
pitch_radius(circ_pitch, teeth, helical) + (
internal
? _dedendum(circ_pitch, clearance, profile_shift=profile_shift)
: _adendum(circ_pitch, profile_shift=profile_shift)
);
/// Function: _root_radius()
/// Usage:
/// rr = _root_radius(circ_pitch, teeth, [helical], [clearance=], [internal=], [profile_shift=]);
/// rr = _root_radius(diam_pitch=, teeth=, [helical=], [clearance=], [internal=], [profile_shift=]);
/// rr = _root_radius(mod=, teeth=, [helical=], [clearance=], [internal=], [profile_shift=]);
/// Topics: Gears
/// Description:
/// Calculates the root radius for the gear, at the base of the dedendum.
/// Arguments:
/// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
/// teeth = The number of teeth on the gear.
/// ---
/// clearance = If given, sets the clearance between meshing teeth.
/// internal = If true, calculate for an internal gear.
/// helical = The helical angle (from vertical) of the teeth on the gear. Default: 0
/// profile_shift = Profile shift factor x.
/// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
/// 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.
/// Example:
/// rr = _root_radius(circ_pitch=5, teeth=11);
/// rr = _root_radius(circ_pitch=5, teeth=16, helical=30);
/// rr = _root_radius(diam_pitch=10, teeth=11);
/// rr = _root_radius(mod=2, teeth=16);
/// Example(2D):
/// pr = _root_radius(circ_pitch=5, teeth=11);
/// #spur_gear2d(pitch=5, teeth=11);
/// color("black")
/// stroke(circle(r=pr),width=0.1,closed=true);
function _root_radius(circ_pitch, teeth, clearance, internal=false, helical=0, profile_shift=0, diam_pitch, mod, pitch) =
let( circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch) )
pitch_radius(circ_pitch, teeth, helical) - (
internal
? _adendum(circ_pitch, profile_shift=profile_shift)
: _dedendum(circ_pitch, clearance, profile_shift=profile_shift)
);
/// Function: _base_radius()
/// Usage:
/// br = _base_radius(circ_pitch, teeth, [pressure_angle], [helical]);
/// br = _base_radius(diam_pitch=, teeth=, [pressure_angle=], [helical=]);
/// br = _base_radius(mod=, teeth=, [pressure_angle=], [helical=]);
/// Topics: Gears
/// Description:
/// Get the base circle for involute teeth, at the base of the teeth.
/// Arguments:
/// pitch = The circular pitch, or distance between teeth around the pitch circle, in mm.
/// teeth = The number of teeth on the gear.
/// pressure_angle = Pressure angle in degrees. Controls how straight or bulged the tooth sides are.
/// helical = The helical angle (from vertical) of the teeth on the gear. Default: 0
/// ---
/// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
/// 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.
/// Example:
/// br = _base_radius(circ_pitch=5, teeth=20, pressure_angle=20);
/// br = _base_radius(circ_pitch=5, teeth=20, pressure_angle=20, helical=30);
/// br = _base_radius(diam_pitch=10, teeth=20, pressure_angle=20);
/// br = _base_radius(mod=2, teeth=18, pressure_angle=20);
/// Example(2D):
/// pr = _base_radius(circ_pitch=5, teeth=11);
/// #spur_gear2d(circ_pitch=5, teeth=11);
/// color("black")
/// stroke(circle(r=pr),width=0.1,closed=true);
function _base_radius(circ_pitch, teeth, pressure_angle=20, helical=0, diam_pitch, mod, pitch) =
let(
circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch),
trans_pa = atan(tan(pressure_angle)/cos(helical))
)
pitch_radius(circ_pitch, teeth, helical) * cos(trans_pa);
2020-10-21 05:24:12 +00:00
2022-03-28 03:06:42 +00:00
// Function: bevel_pitch_angle()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns the pitch cone angle for a bevel gear.
// Topics: Gears, Parts
// See Also: bevel_gear(), pitch_radius(), outer_radius()
2022-03-28 03:06:42 +00:00
// Usage:
// ang = bevel_pitch_angle(teeth, mate_teeth, [drive_angle=]);
2020-10-21 05:24:12 +00:00
// Description:
2023-04-05 00:25:13 +00:00
// Returns the correct pitch cone angle for a bevel gear with a given number of teeth, that is
2022-03-28 03:06:42 +00:00
// matched to another bevel gear with a (possibly different) number of teeth.
// Arguments:
// teeth = Number of teeth that this gear has.
// mate_teeth = Number of teeth that the matching gear has.
// drive_angle = Angle between the drive shafts of each gear. Default: 90º.
// Example:
// ang = bevel_pitch_angle(teeth=18, mate_teeth=30);
// Example(2D):
// t1 = 13; t2 = 19; pitch=5;
// pang = bevel_pitch_angle(teeth=t1, mate_teeth=t2, drive_angle=90);
// color("black") {
// zrot_copies([0,pang])
// stroke([[0,0,0], [0,-20,0]],width=0.2);
// stroke(arc(r=3, angle=[270,270+pang]),width=0.2);
// }
// #bevel_gear(
// pitch=5, teeth=t1, mate_teeth=t2,
// spiral_angle=0, cutter_radius=1000,
// slices=12, anchor="apex", orient=BACK
// );
2022-03-28 03:06:42 +00:00
function bevel_pitch_angle(teeth, mate_teeth, drive_angle=90) =
atan(sin(drive_angle)/((mate_teeth/teeth)+cos(drive_angle)));
// Function: worm_gear_thickness()
2023-04-05 00:25:13 +00:00
// Synopsis: Returns the thickness for a worm gear.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), pitch_radius(), outer_radius()
2022-03-28 03:06:42 +00:00
// Usage:
// thick = worm_gear_thickness(pitch, teeth, worm_diam, [worm_arc=], [crowning=], [clearance=]);
// thick = worm_gear_thickness(mod=, teeth=, worm_diam=, [worm_arc=], [crowning=], [clearance=]);
2022-03-28 03:06:42 +00:00
// Description:
// Calculate the thickness of the worm gear.
2020-10-21 05:24:12 +00:00
// Arguments:
// circ_pitch = The circular pitch, or distance between teeth around the pitch circle, in mm. Default: 5
2020-10-21 05:24:12 +00:00
// teeth = Total number of teeth along the rack. Default: 30
// worm_diam = The pitch diameter of the worm gear to match to. Default: 30
// ---
2020-10-21 05:24:12 +00:00
// worm_arc = The arc of the worm to mate with, in degrees. Default: 60 degrees
2023-04-05 00:25:13 +00:00
// crowning = The amount to oversize the virtual hobbing cutter used to make the teeth, to add a slight crowning to the teeth to make them fit the work easier. Default: 1
2020-10-21 05:24:12 +00:00
// clearance = Clearance gap at the bottom of the inter-tooth valleys.
// mod = The metric module/modulus of the gear, or mm of pitch diameter per tooth.
// 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.
2022-03-28 03:06:42 +00:00
// Example:
// thick = worm_gear_thickness(circ_pitch=5, teeth=36, worm_diam=30);
2022-03-28 03:06:42 +00:00
// thick = worm_gear_thickness(mod=2, teeth=28, worm_diam=25);
// Example(2D):
// circ_pitch = 5; teeth=17;
2022-03-28 03:06:42 +00:00
// worm_diam = 30; starts=2;
// y = worm_gear_thickness(circ_pitch=circ_pitch, teeth=teeth, worm_diam=worm_diam);
2022-03-28 03:06:42 +00:00
// #worm_gear(
// circ_pitch=circ_pitch, teeth=teeth,
2022-03-28 03:06:42 +00:00
// worm_diam=worm_diam,
// worm_starts=starts,
// orient=BACK
// );
// color("black") {
// ycopies(y) stroke([[-25,0],[25,0]], width=0.5);
// stroke([[-20,-y/2],[-20,y/2]],width=0.5,endcaps="arrow");
// }
function worm_gear_thickness(circ_pitch, teeth, worm_diam, worm_arc=60, crowning=1, clearance, diam_pitch, mod, pitch) =
2020-10-21 05:24:12 +00:00
let(
circ_pitch = circular_pitch(pitch, mod, circ_pitch, diam_pitch),
2022-03-28 03:06:42 +00:00
r = worm_diam/2 + crowning,
pitch_thick = r * sin(worm_arc/2) * 2,
pr = pitch_radius(circ_pitch, teeth),
rr = _root_radius(circ_pitch, teeth, clearance, false),
2022-03-28 03:06:42 +00:00
pitchoff = (pr-rr) * sin(worm_arc/2),
thickness = pitch_thick + 2*pitchoff
) thickness;
2023-07-25 01:02:52 +00:00
// Function: gear_dist()
// Synopsis: Returns the distance between two gear centers.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), pitch_radius(), outer_radius()
// Usage:
2023-07-25 01:02:52 +00:00
// dist = gear_dist(pitch, teeth1, teeth2, [helical=], [profile_shift=], [pressure_angle=]);
// dist = gear_dist(mod=, teeth=, [helical=], [profile_shift=], [pressure_angle=]);
// Description:
2023-07-26 00:04:42 +00:00
// Calculate the distance between the centers of two gears with parallel axes, taking into account
// profile shifting and helical angles.
// Arguments:
// pitch = The circular pitch, or distance between teeth around the pitch circle, in mm. Default: 5
2023-07-25 01:02:52 +00:00
// teeth1 = Total number of teeth in the first gear. If given 0, we assume this is a rack or worm.
// teeth2 = Total number of teeth in the second gear. If given 0, we assume this is a rack or worm.
// ---
2023-07-25 01:02:52 +00:00
// helical = The absolute value of the helical angle (from vertical) of the teeth on the gears. Default: 0
// profile_shift1 = Profile shift factor x for the first gear. Default: 0
// profile_shift2 = Profile shift factor x for the second gear. Default: 0
// pressure_angle = The pressure angle of the gear.
// 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.
// Example(2D):
// pitch=5; teeth1=7; teeth2=24;
2023-07-25 01:02:52 +00:00
// d = gear_dist(pitch, teeth1, teeth2);
// spur_gear2d(pitch, teeth1, gear_spin=-90);
// right(d) spur_gear2d(pitch, teeth2, gear_spin=90-180/teeth2);
// Example: Non-parallel Helical Gears BROKEN
// //pitch=5; teeth1=15; teeth2=24; ha1=45; ha2=30; thick=10;
// //d = mesh_radius(pitch, teeth1, teeth2, helical=ha1);
// //mr2 = mesh_radius(pitch, teeth2, helical=ha2);
// //left(mr1) spur_gear(pitch, teeth1, helical=ha1, thickness=thick, gear_spin=-90);
// //right(mr2) xrot(ha1+ha2) spur_gear(pitch, teeth2, helical=ha2, thickness=thick, gear_spin=90-180/teeth2);
// Example(2D): Disable Auto Profile Shifting on the Small Gear
// pitch=5; teeth1=7; teeth2=24;
2023-07-25 01:02:52 +00:00
// d = gear_dist(pitch, teeth1, teeth2, profile_shift1=0);
// spur_gear2d(pitch, teeth1, profile_shift=0, gear_spin=-90);
// right(d) spur_gear2d(pitch, teeth2, gear_spin=90-180/teeth2);
// Example(2D): Manual Profile Shifting
// pitch=5; teeth1=7; teeth2=24; ps1 = 0.5; ps2 = -0.2;
2023-07-25 01:02:52 +00:00
// d = gear_dist(pitch, teeth1, teeth2, profile_shift1=ps1, profile_shift2=ps2);
// spur_gear2d(pitch, teeth1, profile_shift=ps1, gear_spin=-90);
// right(d) spur_gear2d(pitch, teeth2, profile_shift=ps2, gear_spin=90-180/teeth2);
2023-07-25 01:02:52 +00:00
function gear_dist(
circ_pitch,
2023-07-25 01:02:52 +00:00
teeth1,
teeth2,
helical=0,
2023-07-25 01:02:52 +00:00
profile_shift1,
profile_shift2,
pressure_angle=20,
diam_pitch,
mod,
pitch
) =
let(
2023-07-25 01:02:52 +00:00
mod = circular_pitch(pitch, mod, circ_pitch, diam_pitch)/PI,
profile_shift1 = default(profile_shift1, teeth1>0? auto_profile_shift(teeth1,pressure_angle,helical) : 0),
profile_shift2 = default(profile_shift2, teeth2>0? auto_profile_shift(teeth2,pressure_angle,helical) : 0),
pa_eff = _working_pressure_angle(teeth1,profile_shift1,teeth2,profile_shift2,pressure_angle,helical),
pa_transv = atan(tan(pressure_angle)/cos(helical))
)
mod*(teeth1+teeth2)*cos(pa_transv)/cos(pa_eff)/cos(helical)/2;
function _invol(a) = tan(a) - a*PI/180;
function _working_pressure_angle(teeth1,profile_shift1, teeth2, profile_shift2, pressure_angle, helical) =
let(
pressure_angle = atan(tan(pressure_angle)/cos(helical)),
rhs = 2*(profile_shift1+profile_shift2)/(teeth1+teeth2)*cos(helical)*tan(pressure_angle) + _invol(pressure_angle),
pa_eff = root_find(function (x) _invol(x)-rhs, 5, 75)
)
pa_eff;
2023-07-26 00:04:42 +00:00
// Function: gear_dist_skew()
// Usage:
// d = gear_dist_skew(circ_pitch, teeth1, profile_shift1, h
// Description:
// Calculate the distance between two helical gears that mesh with non-parallel axes, taking into account
// profile shift and the helical angles.
function gear_dist_skew(mod,teeth1,profile_shift1=0, helical1, teeth2, profile_shift2=0, helical2, pressure_angle=20) =
let(
pa_normal_eff = _working_normal_pressure_angle_skew(teeth1,profile_shift1,helical1,teeth2,profile_shift2,helical2,pressure_angle),
dist_adj = 0.5*(teeth1/cos(helical1)^3+teeth2/cos(helical2)^3)*(cos(pressure_angle)/cos(pa_normal_eff)-1),
ff=echo(y=dist_adj,pa_normal_eff)
)
mod*(teeth1/2/cos(helical1)+teeth2/2/cos(helical2)+dist_adj);
function _working_normal_pressure_angle_skew(teeth1,profile_shift1,helical1, teeth2, profile_shift2, helical2, pressure_angle) =
let(
rhs = 2*(profile_shift1+profile_shift2)/(teeth1/cos(helical1)^3+teeth2/cos(helical2)^3)*tan(pressure_angle) + inv(pressure_angle),
fdaseee= echo(rhs=rhs),
pa_eff_normal = root_find(function (x) inv(x)-rhs, 5, 75)
)
pa_eff_normal;
// Function: gear_skew_angle()
// Usage:
// ang = gear_skew_angle(....
// Description:
// Compute the correct skew angle between the axes of two helical gears.
function gear_skew_angle(mod,teeth1,profile_shift1,helical1,teeth2, profile_shift2,helical2,pressure_angle=20)=
2023-07-26 00:16:33 +00:00
profile_shift1==0 && profile_shift2==0 ? helical1+helical2
:
2023-07-26 00:04:42 +00:00
let(
//mod = circular_pitch(pitch, mod, circ_pitch, diam_pitch)/PI,
a = gear_dist_skew(mod,teeth1,profile_shift1,helical1,teeth2, profile_shift2,helical2,pressure_angle),
d1 = 2*pitch_radius(mod=mod,teeth=teeth1,helical=helical1),
d2 = 2*pitch_radius(mod=mod,teeth=teeth2,helical=helical2),
dw1 = 2*a*d1/(d1+d2),
dw2 = 2*a*d2/(d1+d2),
beta1 = atan(dw1/d1*tan(helical1)),
beta2 = atan(dw2/d2*tan(helical2))
)
beta1+beta2;
// Function: get_profile_shift()
// Usage:
// total_shift = get_profile_shift(desired,....)
// Description:
// Compute the total profile shift, split between two gears, needed to place those gears with a specified separation.
// If the requested separation is impossible, returns nan. Note that the profile shift returned may also be impractically
// large.
// Arguments:
// circ_pitch = circular pitch of gear teeth
// teeth1 = number of teeth on first gear
// teeth2 = number of teeth on second gear
// pressure_angle = normal pressure angle of gear teeth. Default: 20
// mod = gear module, an alternative to circ_pitch for giving gear size
// diam_pitch = specify dimetral pitch
function get_profile_shift(desired,circ_pitch,teeth1,teeth2,pressure_angle=20,mod,diam_pitch,pitch) =
let(
mod = circular_pitch(pitch, mod, circ_pitch, diam_pitch)/PI,
pa_eff = acos(mod*(teeth1+teeth2)*cos(pressure_angle)/2/desired)
)
(_invol(pa_eff)-_invol(pressure_angle))/2/tan(pressure_angle) * (teeth1+teeth2);
// Function: auto_profile_shift()
// Synopsis: Returns the recommended profile shift for a gear.
// Topics: Gears, Parts
// See Also: worm(), worm_gear(), pitch_radius(), outer_radius()
// Usage:
// x = auto_profile_shift(teeth, pressure_angle);
// x = auto_profile_shift(teeth, min_teeth=);
// Description:
// Calculates the recommended profile shift to avoid gear tooth undercutting.
// Arguments:
// teeth = Total number of teeth in the gear.
// pressure_angle = The pressure angle of the gear.
2023-07-25 01:02:52 +00:00
// helical = helical angle
// ---
// min_teeth = If given, the minimum number of teeth on a gear that has acceptable undercut.
2023-07-25 01:02:52 +00:00
function auto_profile_shift(teeth, pressure_angle=20, helical, min_teeth) =
let(
min_teeth = is_undef(min_teeth)
? 2 / pow(sin(pressure_angle),2)
: min_teeth
)
teeth > floor(min_teeth)? 0 :
1 - (teeth / min_teeth);
2020-10-21 05:24:12 +00:00
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap