forked from BelfrySCAD/BOSL2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gears.scad
4623 lines (4457 loc) · 230 KB
/
gears.scad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//////////////////////////////////////////////////////////////////////////////////////////////
// LibFile: gears.scad
// Spur Gears, Bevel Gears, Racks, Worms and Worm Gears.
// Inspired by code by Leemon Baird, 2011, [email protected]
// Includes:
// include <BOSL2/std.scad>
// include <BOSL2/gears.scad>
// FileGroup: Parts
// FileSummary: Gears, racks, worms, and worm gears.
//////////////////////////////////////////////////////////////////////////////////////////////
_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)
circular_pitch(diam_pitch=diam_pitch) :
mod != undef?
assert(is_finite(mod) && mod>0)
circular_pitch(mod=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,dflt=10) =
_inherit_gear_param("thickness", thickness, $parent_gear_thickness, dflt=dflt);
// Section: Quick Introduction to Gears
// This section gives a quick overview of gears with a focus on the information you need
// to know to understand the gear parameters and create some gears. The topic of gears is very complex and highly technical and
// this section provides the minimal information needed for gear making. If you want more information about the
// details of gears, consult the references below, which are the ones that we consulted when writing the library code.
// - Tec Science
// * [Involute Gears](https://www.tec-science.com/mechanical-power-transmission/involute-gear/geometry-of-involute-gears/)
// * [Gear engagement](https://www.tec-science.com/mechanical-power-transmission/involute-gear/meshing-line-action-contact-pitch-circle-law/)
// * [Gears meshing with racks](https://www.tec-science.com/mechanical-power-transmission/involute-gear/rack-meshing/)
// * [Gear undercutting](https://www.tec-science.com/mechanical-power-transmission/involute-gear/undercut/)
// * [Profile shifting](https://www.tec-science.com/mechanical-power-transmission/involute-gear/profile-shift/)
// * [Detailed gear calculations](https://www.tec-science.com/mechanical-power-transmission/involute-gear/calculation-of-involute-gears/)
// * [Worm drive](https://www.tec-science.com/mechanical-power-transmission/gear-types/worms-and-worm-gears/)
// * [Bevel gears](https://www.tec-science.com/mechanical-power-transmission/gear-types/bevel-gears/)
// - SDPSI (A long document covering a variety of gear types and gear calculations)
// * [Elements of Gear Technology](https://www.sdp-si.com/resources/elements-of-metric-gear-technology/index.php)
// - Drivetrain Hub (A collection of "notebooks" on some gear topics)
// * [Gear Geometry, Strength, Tooling and Mechanics](https://drivetrainhub.com/notebooks/#toc)
// - Crown Face Gears
// * [Crown Gearboxes](https://mag.ebmpapst.com/en/industries/drives/crown-gearboxes-efficiency-energy-savings-decentralized-drive-technology_14834/)
// * [Crown gear pressure angle](https://mag.ebmpapst.com/en/industries/drives/the-formula-for-the-pressure-angle_14624/)
// * [Face Gears: Geometry and Strength](https://www.geartechnology.com/ext/resources/issues/0107x/kissling.pdf)
// Subsection: Involute Spur Gears
// The simplest gear form is the involute spur gear, which is an extrusion of a two dimensional form.
// Figure(3D,Med,NoAxes,VPT=[4.62654,-1.10349,0.281802],VPR=[55,0,25],VPD=236.957): Involute Spur Gear
// spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,shaft_diam=15);
// Continues:
// The term "involute" refers to the shape of the teeth: the curves of the teeth are involutes of circles,
// which are curves that optimize gear performance.
// 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.
// $fn=128;
// intersection(){
// spur_gear2d(mod=5,teeth=30,pressure_angle=20);
// back(82)rect([45, 20],anchor=BACK);
// }
// color("black"){
// stroke(arc(r=_root_radius(mod=5,teeth=30),angle=[70,110]),width=.25);
// 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);
// back(63.5)right(24.2)text("root circle",size=2.5);
// 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("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);
// }
// stroke(arc(r=pitch_radius(mod=5,teeth=30),angle=[87,87+12]),width=.4,endcaps="arrow2",color="red");
// color([1,0,0,1]) back(70)right(-13)zrot(4)text("circular pitch", size=2.5);
// Continues:
// The size of the teeth can be specified as the *circular pitch*, which is the tooth width, or more precisely,
// 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, ratio of the diameter of the gear to the number of teeth: `m=d/teeth`.
// The module is hence the circular pitch divided by a factor of π. 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 π 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.
// .
// Note that there is no direct way to specify the size of a gear. The diameter of a gear depends on its tooth count
// and tooth size. If you want a gear with a particular diameter you can get close by seeting the module to `d/teeth`,
// but that specifies the pitch circle, so the gear teeth will have a somewhat larger radius. You should **not**
// apply scale() to gears. Always change their size by adjusting the tooth size parameters.
// .
// Basic gears as shown above will mesh when their pitch 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.
// pang = [30,20,14.5];
// ycopies(n=3, spacing=25){
// 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);
// }
// 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. This defaults to `module/4`.
// Figure(2D,Med,NoAxes,VPT=[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.
// intersection(){
// rack2d(mod=5, teeth=10, bottom=15, pressure_angle=14.5);
// rect([35,20]);
// }
// color("lightgreen")render()
// intersection(){
// back(gear_dist(mod=5, teeth1=146, teeth2=0 ,profile_shift1=0))
// spur_gear2d(mod=5, teeth=146, 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.
// Is is best to avoid gears with very small numbers of teeth when possible.
// Figure(2D,Med,NoAxes,VPT=[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.
// ang=16;
// rack2d(mod=5, teeth=3, bottom=15, pressure_angle=14.5, rounding=0);
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang/360)
// 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, shaft_diam=5);
// Subsection: Corrected Gears and Profile Shifting
// 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 so it no longer meshes at the pitch circle.
// A profile shift of `x`
// will increase the mesh distance by approximately `x*m` where `m` is the gear module. The exact adjustment,
// which you compute with {{gear_dist()}}, is a complex calculation that depends on the profile shifts of both meshing gears. 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.
// Profile shifting also changes the effective pressure angle of the gear engagement.
// Figure(2D,Med,NoAxes): The green gear is a 7 tooth gear without profile shifting. In yellow is the same gear, profile shifted. Note that the teeth too longer narrow at their base. Also note that the effective root circle has a larger radius, and the teeth are also longer.
// spur_gear2d(mod=5, teeth=7);
// color("green")spur_gear2d(mod=5, teeth=7, profile_shift=0);
// Continues:
// 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 may be 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.
// Figure(2D,Med,NoAxes,VPT=[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.
// $fn=32;
// ang1=-20;
// ang2=20;
// color("blue")
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang1/360)
// left(3*5*PI/2)
// back(gear_dist(mod=5,teeth1=5,profile_shift1=0,teeth2=0,pressure_angle=14.5))
// zrot(ang1)
// spur_gear2d(mod=5, teeth=5, profile_shift=0, pressure_angle=14.5, shaft_diam=2);
// color("green")
// left(2*PI*pitch_radius(mod=5, teeth=5)*ang2/360)
// right(3*5*PI/2)
// back(gear_dist(mod=5, teeth1=5, teeth2=0,pressure_angle=14.5))
// zrot(ang2)
// spur_gear2d(mod=5, teeth=5, pressure_angle=14.5, shaft_diam=2);
// rack2d(teeth=4, bottom=15, mod=5, pressure_angle=14.5);
// Continues:
// Profile shifting brings with it another complication: in order to maintain the specified clearance, the tips of the
// gear teeth need to be shortened. The shortening factor depends on characteristics of both gears, so it cannot
// be automatically incorporated. (Consider the situation where one gear mates with multiple other gears.) With modest
// profile shifts, you can probably ignore this adjustment, but with more extreme profile shifts, it may be important.
// You can compute the shortening parameter using {{gear_shorten()}}. Note that the actual shortening distance is obtained
// by scaling the shortening factor by the gear's module.
// Figure(2D,Big,NoAxes,VPT=[55.8861,-4.31463,8.09832],VPR=[0,0,0],VPD=325.228): With large profile shifts the teeth need to be shortened or they don't have clearance in the valleys of the teeth in the meshing gear.
// teeth1=25;
// teeth2=19;
// mod=4;
// ps1 = 0.75;
// ps2 = 0.75;
// d = gear_dist(mod=mod, teeth1,teeth2,0,ps1,ps2);
// color("lightblue")
// spur_gear2d(mod=mod,teeth=teeth1,profile_shift=ps1,gear_spin=-90);
// right(d)
// spur_gear2d(mod=mod,teeth=teeth2,profile_shift=ps2,gear_spin=-90);
// right(9)stroke([[1.3*d/2,0],[d/2+4,0]], endcap2="arrow2",color="black");
// fwd(2)right(d/2+25)color("black"){back(4)text("No clearance",size=6);
// fwd(4)text("at tooth tip",size=6);}
// Figure(2D,Big,NoAxes,VPT=[55.8861,-4.31463,8.09832],VPR=[0,0,0],VPD=325.228): Applying the correct shortening factor restores the clearance to its set value.
// teeth1=25;
// teeth2=19;
// mod=4;
// ps1 = 0.75;
// ps2 = 0.75;
// d = gear_dist(mod=mod, teeth1,teeth2,0,ps1,ps2);
// shorten=gear_shorten(teeth1,teeth2,0,ps1,ps2);
// color("lightblue")
// spur_gear2d(mod=mod,teeth=teeth1,profile_shift=ps1,shorten=shorten,gear_spin=-90);
// right(d)
// spur_gear2d(mod=mod,teeth=teeth2,profile_shift=ps2,shorten=shorten,gear_spin=-90);
// right(9)stroke([[1.3*d/2,0],[d/2+4,0]], endcap2="arrow2",color="black");
// fwd(2)right(d/2+25)color("black"){back(4)text("Normal",size=6);
// fwd(4)text("Clearance",size=6);}
// Subsection: 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(3D,Med,NoAxes,VPT=[3.5641,-7.03148,4.86523],VPR=[62.7,0,29.2],VPD=263.285): A Helical Gear
// spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=35,helical=-29,shaft_diam=15,slices=15);
// 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 35 must mesh with one
// that has an angle of −35. The industry convention refers to these as left-handed and right handed. In
// this library, positive helical angles produce a left handed gear and negative angles produce a right handed gear.
// Figure(3D,Med,NoAxes,VPT=[73.6023,-29.9518,-12.535],VPR=[76,0,1.2],VPD=610): Left and right handed helical gears at 35 degrees.
// spur_gear(mod=5, teeth=20, helical=35, thickness=70,slices=15);
// right(150)
// spur_gear(mod=5, teeth=20, helical=-35, thickness=70,slices=15);
// down(22)
// left(60)
// fwd(220)
// rot($vpr)
// color("black")text3d("left handed right handed",size=18);
// down(52)
// left(55)
// fwd(220)
// rot($vpr)
// color("black")text3d("helical=35 helical=−35",size=18);
// Continues:
// The pitch circle of a helical gear is larger compared to a spur gear
// by the cosine of the helical angle, so you cannot simply drop helical gears in to replace spur gears without
// making other adjustments. This dependence does allow you to make
// make much bigger spacing adjustments than are possible with profile shifting—without changing the tooth count.
// The {{gear_dist()}} function will also compute the appropriate gear spacing for helical gears.
// 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,Med,Frames=10,NoAxes,VPT=[43.8006,15.9214,3.52727],VPR=[62.3,0,20.3],VPD=446.129): Meshing compatible helical gears
// zrot($t*360/18)
// spur_gear(mod=5, teeth=18, pressure_angle=20, thickness=25, helical=-29, shaft_diam=15);
// 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, shaft_diam=15);
// Continues:
// Helical gears can mesh in a second manner that is different from spur gears: they can turn on skew, or crossed axes. These are also
// sometimes called "screw gears". The general requirement for two non-profile-shifted 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. If helical gears are profile shifted, then in addition to adjusting the distance between the
// gears, a small adjustment in the angle is needed, so profile shifted gears won't mesh exactly at the sum of their angles.
// The calculation for gear spacing is different for skew axis gears than for parallel gears, so you do this using {{gear_dist_skew()}},
// and if you use profile shifting, then you can compute the angle using {{gear_skew_angle()}}.
// Figure(Anim,Med,NoAxes,Frames=10,VPT=[44.765,6.09492,-3.01199],VPR=[55.7,0,33.2],VPD=401.289): Two helical gears meshing with axes at a 45 degree angle
// dist = gear_dist_skew(mod=5, teeth1=18, teeth2=18, helical1=22.5,helical2=22.5);
// axiscolor="darkgray";
// down(10)color(axiscolor) cyl(d=15, l=145);
// zrot($t*360/18)
// color("lightblue")spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=22.5,shaft_diam=15);
// right(dist)
// xrot(45) {color(axiscolor)cyl(d=15,l=85);
// zrot(360/18/2)
// zrot(-$t*360/18)
// spur_gear(mod=5,teeth=18,pressure_angle=20,thickness=25,helical=22.5,shaft_diam=15);}
// Subsection: Herringbone Gears
// The herringbone gear is made from two stacked helical gears with opposite angles. This design 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(3D,Med,NoAxes,VPT=[3.5641,-7.03148,4.86523],VPR=[62.7,0,29.2],VPD=263.285): A herringbone gear
// spur_gear(mod=5, teeth=16, pressure_angle=20, thickness=35, helical=-20, herringbone=true, shaft_diam=15);
// Subsection: Ring Gears (Internal Gears)
// A ring gear (or internal gear) is a gear where the teeth are on the inside of a circle. Such gears must be mated
// to a regular (external) gear, which rotates around the inside.
// Figure(2D,Med,NoAxes,VPT=[0.491171,1.07815,0.495977],VPR=[0,0,0],VPD=292.705): A interior or ring gear (yellow) with a mating spur gear (blue)
// teeth1=18;
// teeth2=30;
// ps1=undef;
// ps2=auto_profile_shift(teeth=teeth1);
// mod=3;
// d = gear_dist(mod=mod, teeth1=teeth1, teeth2=teeth2,profile_shift1=ps1, profile_shift2=ps2,helical=0, internal2=true);
// ang = 0;
// ring_gear2d(mod=mod, teeth=teeth2,profile_shift=ps2,helical=0,backing=4);
// zrot(ang*360/teeth2)
// color("lightblue")
// fwd(d)
// spur_gear2d(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=0);
// Continues:
// Ring gears are subject to all the usual mesh requirements: the teeth must be the same size, the pressure angles must
// match and they must have opposite helical angles. The {{gear_dist()}} function can give the center separation of
// a ring gear and its mating spur gear. Ring gears have additional complications that tend to arise when the number of
// teeth is small or the teeth counts of the ring gear and spur gear are too close together. The mating spur gear must
// have few enough teeth so that the teeth don't interfere on the other side of the ring. Very small spur gears can interfere
// on the tips of the ring gear's teeth.
// Figure(2D,Med,NoAxes,VPT=[-1.16111,0.0525612,0.495977],VPR=[0,0,0],VPD=213.382): The red regions show interference between the two gears: the 18 tooth spur gear does not fit inside the 20 tooth ring gear.
// teeth1=18;
// teeth2=20;
// ps1=undef;
// ps2=auto_profile_shift(teeth=teeth1);
// mod=3;
// d = gear_dist(mod=mod, teeth1=teeth1, teeth2=teeth2,profile_shift1=ps1, profile_shift2=ps2,helical=0, internal2=true);
// ang = 0;
// color_overlaps(){
// ring_gear2d(mod=mod, teeth=teeth2,profile_shift=ps2,helical=0,backing=4);
// zrot(ang*360/teeth2)
// fwd(d)
// spur_gear2d(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=0);
// }
// Figure(2D,Big,NoAxes,VPT=[10.8821,-26.1226,-0.0685569],VPD=43.9335,VPR=[0,0,16.8]): Interference at teeth tips, shown in red, with a 5 tooth and 19 tooth gear.
// $fn=128;
// teeth1=5;
// teeth2=19;
// ps1=0;
// ps2=0;
// mod=3;
// d = gear_dist(mod=mod, teeth1=teeth1, teeth2=teeth2,profile_shift1=ps1, profile_shift2=ps2,helical=0, internal2=true);
// ang = 1;
// color_overlaps(){
// ring_gear2d(mod=mod, teeth=teeth2,profile_shift=ps2,helical=0,backing=4);
// zrot(ang*360/teeth2)
// fwd(d)
// spur_gear2d(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=0);
// }
// Continues:
// The tooth tip interference can often be controlled using profile shifting of the ring gear, but another requirement is
// that the profile shift of the ring gear must be at least as big as the profile shift of the mated spur gear. In order
// to ensure that this condition holds, you may need to use {{auto_profile_shift()}} to find the profile shift that is
// automatically applied to the spur gear you want to use.
// Figure(2D,Med,VPT=[4.02885,-46.6334,1.23363],VPR=[0,0,6.3],VPD=75.2671,NoAxes): Ring gear without profile shifting doesn't have room for the fat profile shifted teeth of the 5-tooth spur gear, with overlaps shown in red.
// $fn=128;
// teeth1=5;
// teeth2=35;
// ps1=undef;
// ps2=0;
// mod=3;
// d=45-.7;
// ang = .5;
// color_overlaps(){
// ring_gear2d(mod=mod, teeth=teeth2,profile_shift=ps2,helical=0,backing=4);
// zrot(ang*360/teeth2)
// fwd(d)
// spur_gear2d(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=0);
// }
// Figure(2D,Med,VPT=[9.87969,-45.6706,0.60448],VPD=82.6686,VPR=[0,0,11],NoAxes): When the ring gear is profile shifted to match the spur gear, then the gears mesh without interference.
// $fn=128;
// teeth1=5;
// teeth2=35;
// ps1=undef;
// ps2=auto_profile_shift(teeth=teeth1);
// mod=3;
// d = gear_dist(mod=mod, teeth1=teeth1, teeth2=teeth2,profile_shift1=ps1, profile_shift2=ps2,helical=0, internal2=true);
// ang = .5;
// color_overlaps(){
// ring_gear2d(mod=mod, teeth=teeth2,profile_shift=ps2,helical=0,backing=4);
// zrot(ang*360/teeth2)
// fwd(d)
// spur_gear2d(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=0);
// }
// Figure(3D,Med,NoAxes,VPT=[2.48983,2.10149,0.658081],VPR=[70.4,0,123],VPD=237.091): A helical ring gear (yellow) mating with the compatible spur gear (blue)
// $fn=128;
// teeth1=18;
// teeth2=30;
// ps1=undef;
// ps2=auto_profile_shift(teeth=teeth1);
// mod=3;
// d = gear_dist(mod=mod, teeth1=teeth1, teeth2=teeth2,profile_shift1=ps1, profile_shift2=ps2,helical=30, internal2=true);
// ang = 0;
// ring_gear(mod=mod, teeth=teeth2,profile_shift=ps2,backing=4,helical=30,thickness=15);
// zrot(ang*360/teeth2)
// color("lightblue")
// fwd(d)
// spur_gear(mod=mod, teeth=teeth1, profile_shift=ps1,gear_spin=-ang*360/teeth1,helical=-30,thickness=15);
// Subsection: Worm Drive
// A worm drive is a gear system for connecting skew shafts at 90 degrees. They offer higher load capacity compared to
// crossed helical gears. The assembly is driven by the "worm", which is a gear that resembles a screw.
// Like a screw, it can have one, or several starts. These starts correspond to teeth on a helical gear;
// in fact, the worm can be regarded as a type of helical gear at a very extreme angle, where the teeth wrap
// around the gear. The worm mates with the "worm gear" which is also called the "worm wheel". The worm gear
// resembles a helical gear at a very slight angle.
// Figure(3D,Med,NoAxes,VPT=[38.1941,-7.67869,7.95996],VPR=[56.4,0,25],VPD=361.364): Worm drive assembly, with worm on the left and worm gear (worm wheel) on the right. When the worm turns, its screwing action drives the worm gear.
// starts=2;
// ps=0;
// dist_ba=0;
// gear_ba=0;
// worm(
// d=44, // mate_teeth=30,
// circ_pitch=3*PI,
// starts=starts,orient=BACK);
// right(worm_dist(d=44,mod=3,teeth=30, starts=starts,profile_shift=ps,backlash=dist_ba))
// zrot(360/30*.5)
// worm_gear(
// circ_pitch=3*PI,
// teeth=30,
// worm_diam=44,profile_shift=ps,
// worm_starts=starts,backlash=gear_ba);
// color("black"){
// rot($vpr)left(45)back(25)text3d("worm",size=8);
// rot($vpr)right(55)back(27)text3d("worm gear",size=8);
// }
// Continues:
// A close look at the worm gear reveals that it differs significantly from a helical or spur gear.
// This gear is an "enveloping" gear, which is designed to follow the curved profile of the worm,
// resulting in much better contact between the teeth of the worm and the teeth of the worm gear.
// The worm shown above is a cylindrical worm, which is the most common type.
// It is possible to design the worm to follow the curved shape of its mated gear, resulting
// in an enveloping (also called "globoid") worm. This type of worm makes better contact with
// the worm gear, but is less often used due to manufacturing complexity and consequent expense.
// Figure(3D,Big,NoAxes,VPT=[0,0,0],VPR=[192,0,180],VPD=172.84): A cylindrical worm appears on the left in green. Note its straight sides. The enveloping (globoid) worm gears appears on the right in green. Note that its sides curve so several teeth can mate with the worm gear, and it requires a complex tooth form
// tilt=20;
// starts=1;
// ps=0;
// pa=27;
// dist_ba=0;
// gear_ba=0;
// xdistribute(spacing=25){
// xflip()yrot(-tilt)
// union(){
// color("lightgreen")
// xrot(90)
// zrot(-90)
// enveloping_worm( mate_teeth=60,$fn=128,
// d=14, pressure_angle=pa, mod=3/2,
// starts=starts);
// right(worm_dist(d=14,mod=3/2,teeth=60, starts=starts,profile_shift=ps,backlash=dist_ba,pressure_angle=pa))
// zrot(360/30*.25)
// worm_gear(
// mod=3/2,pressure_angle=pa,
// teeth=60,crowning=0,
// worm_diam=14,profile_shift=ps,
// worm_starts=starts,backlash=gear_ba);
// }
// yrot(-tilt)
// union(){
// color("lightgreen")
// xrot(90)
// zrot(-90)
// worm(l=43, $fn=128,
// d=14, pressure_angle=pa, left_handed=true,
// mod=3/2,//circ_pitch=3*PI/2,
// starts=starts);
// right(worm_dist(d=14,mod=3/2,teeth=60, starts=starts,profile_shift=ps,backlash=dist_ba,pressure_angle=pa))
// zrot(360/30*.25)
// worm_gear(
// mod=3/2,pressure_angle=pa,
// teeth=60,crowning=0,left_handed=true,
// worm_diam=14,profile_shift=ps,
// worm_starts=starts,backlash=gear_ba);
// }
// }
// Continues:
// As usual, a proper mesh requires that the pressure angles match and the teeth of the worm and worm gear
// are the same size. Additionally the worm gear must be constructed to match the diameter of the worm
// and the number of starts on the worm. Note that the number of starts changes the angle at of the
// teeth on the worm, and hence requires a change to the angle of teeth on the worm gear.
// Of course an enveloping worm needs to know the diameter of the worm gear; you provide this
// information indirectly by giving the number of teeth on the worm gear.
// The {{worm_dist()}} function will give the correct center spacing for the worm from its mating worm gear.
// .
// Worm drives are often "self-locking", which means that torque transmission can occur only from the worm to the worm gear,
// so they must be driven by the worm. Self-locking results from the small lead angle of the worm threads, which produces
// high frictional forces at contact. A multi-start worm has a higher lead angle and as a result is less likely
// to be self-locking, so a multi-start worm can be chosen to avoid self-locking.
// Since self-locking is associated with friction, self-locking drives have lower efficiency,
// usually less than 50%. Worm drive efficiency can exceed 90% if self-locking is not required. One consideration
// with self-locking systems is that if the worm gear moves a large mass and the drive is suddenly shut off, the
// worm gear is still trying to move due to inertia, which can create large loads that fracture the worm.
// In such cases, the worm cannot be stopped abruptly but must be allowed to rotate a little further (called "over travel")
// after switching off the drive.
// Subsection: Bevel Gears
// Bevel gearing is another way of dealing with intersecting gear shafts. For bevel gears, the teeth centers lie on
// the surface of an imaginary cone, which is the "pitch cone" of the bevel gear. Two bevel gears can mesh when their pitch cone
// apexes coincide and the cones touch along their length. The teeth of bevel gears shrink as they get closer to the center of the gear.
// Tooth dimensions and pitch diameter (the base of the pitch cone) are referenced to the outer end of the teeth.
// Note that the pitch radius, computed the same was as for other gears, gives the radius of the pitch cone's base.
// Bevel gears can be made with straight teeth, analogous to spur gears, and with the
// same disadvantage of sudden full contact that is noisy. Spiral teeth are analogous to helical
// teeth on cylindrical gears: the teeth engage gradually and smoothly, transmitting motion more smoothly
// and quietly. Also like helical gears, they have the disadvantage of introducing axial forces, and
// usually they can only operate in one rotation direction.
// A third type of tooth is the zerol tooth, which has curved teeth like the spiral teeth,
// but with a zero angle. These share advantages of straight teeth and spiral teeth: they are quiet like
// straight teeth but they lack the axial thrust of spiral gears, and they can operate in both directions.
// They are also reportedly stronger than either spiral or bevel gears.
// Figure(3D,Med,VPT=[-5.10228,-3.09311,3.06426],VPR=[67.6,0,131.9],VPD=237.091,NoAxes): Straight tooth bevel gear with 45 degree angled teeth. To get a gear like this you must specify a spiral angle of zero and a cutter radius of zero. This gear would mate with a copy of itself and would change direction of rotation without changing the rotation rate.
// bevel_gear(mod=3,teeth=35,mate_teeth=35,face_width=20,spiral=0,cutter_radius=0);
// Figure(3D,Med,VPT=[-5.10228,-3.09311,3.06426],VPR=[67.6,0,131.9],VPD=237.091,NoAxes): Straight tooth bevel gear with 45 degree angled teeth. A gear like this has a positive spiral angle, which determines how sloped the teeth are and a positive cutter radius, which determines how curved the teeth are.
// bevel_gear(mod=3,teeth=35,mate_teeth=35,face_width=20,slices=12);
// Figure(3D,Med,VPT=[-5.10228,-3.09311,3.06426],VPR=[67.6,0,131.9],VPD=237.091,NoAxes): Zerol tooth bevel gear with 45 degree angled teeth. A gear like this has a spiral angle of zero, but a positive cutter radius, which determines how curved the teeth are.
// bevel_gear(mod=3,teeth=35,mate_teeth=35,face_width=20,spiral=0,slices=12);
// Continues:
// Bevel gears have demanding requirements for successful mating of two gears. Of course the tooth size
// and pressure angle must match. But beyond that, their pitch cones have to meet at their points.
// This means that if you specify the tooth counts
// of two gears and the desired shaft angle, then that information completely determines the pitch cones, and hence
// the geometry of the gear. You cannot simply mate two arbitary gears that have the same tooth size
// and pressure angle like you can with helical gears: the gears must be designed in pairs to work together.
// .
// It is most common to design bevel gears so operate with their shafts at 90 degree angles, but
// this is not required, and you can design pairs of bevel gears for any desired shaft angle.
// Note, however, that some shaft angles may result in extreme bevel gear configurations.
// Figure(3D,Med,NoAxes,VPT=[-1.42254,-1.98925,13.5702],VPR=[76,0,145],VPD=263.435): Two zerol bevel gears mated with shafts at 90 degrees.
// bevel_gear(mod=3,teeth=35,face_width=undef,spiral=0,mate_teeth=15,backing=3);
// cyl(h=28,d=3,$fn=16,anchor=BOT);
// color("lightblue")left(pitch_radius(mod=3,teeth=35))up(pitch_radius(mod=3,teeth=15))
// yrot(90){zrot(360/15/2)bevel_gear(mod=3,teeth=15,face_width=undef,spiral=0,right_handed=true,mate_teeth=35);
// cyl(h=57,d=3,$fn=16,anchor=BOT);}
// Figure(3D,Med,NoAxes,VPT=[2.01253,-0.673328,8.98056],VPD=263.435,VPR=[79.5,0,68.6]): Two zerol bevel gears mated with shafts at a 115.38 deg angle. This is a planar bevel gear. The axes intersect on the pitch base of the yellow gear. If the blue gear is tipped slightly more its shaft will intersect the shaft of the yellow gear underneath that gear's pitch base, indicating an impossible angle for a normal bevel gear at this pair of teeth counts.
// ang=acos(-15/35);
// bevel_gear(mod=3,35,15,ang,spiral=0,face_width=undef,backing=5,anchor="apex")
// cyl(h=25,d=3,$fn=16,anchor=BOT);
// color("lightblue")
// xrot(ang)
// bevel_gear(mod=3,15,35,ang,spiral=0,face_width=undef,right_handed=true,anchor="apex")
// cyl(h=70,d=3,$fn=16,anchor=BOT);
// Continues:
// In the above figure you can see a flat bevel gear. Such a bevel gear is called a planar bevel gear or
// sometimes also a crown gear. The latter term may be confusing because it also refers to a similar looking
// but very different type of gear that is described below. A planar bevel gear can only mate with another
// compatible bevel gear. It has a degenerate cone with its apex on the gear itself, so the mating pinion gear cannot
// mate at a 90 degree angle because if it did, its cone could not meet the center of the planar bevel gear.
// If you request a larger shaft angle, the teeth of the bevel gear will tilt inward, producing an internal bevel gear.
// Gears with this design are rarely used. The mate of an interior gear is always an exterior gear.
// Figure(Med,VPT=[-1.07698,0.67915,-2.25898],VPD=263.435,VPR=[69.7,0,49.3],NoAxes): Internal bevel gear (yellow) mated to an external bevel gear (blue) to achieve a 135 degree shaft angle.
// ang=135;
// bevel_gear(mod=3,35,15,ang,spiral=0,cone_backing=false);
// down(15)cyl(h=40,d=3,$fn=16,anchor=BOT);
// color("lightblue")
// back(pitch_radius(mod=3,teeth=35)+pitch_radius(mod=3,teeth=15))
// xrot(ang,cp=[0,-pitch_radius(mod=3,teeth=15),0]){
// bevel_gear(mod=3,15,35,ang,right_handed=true,spiral=0);
// cyl(h=40,d=3,$fn=16,anchor=BOT);
// }
// Subsection: Crown Gears (Face Gears)
// Crown gears, sometimes called Face Crown Gears or just Face Gears, are gears with teeth pointing straight up so
// the gear resembles a crown. This type of gear is not the same as a bevel gear with vertical teeth, which would mate
// to another bevel gear. A crown gear mates to a spur gear at a ninety degree angle. A feature of the crown gear assembly
// is that the spur gear can shift along its axis without affecting the mesh.
// Figure(Med,NoAxes,VPT=[-2.19006,-1.67419,-4.49379],VPR=[67.6,0,131.9],VPD=113.4): A Crown or Face gear with its mating spur gear in blue.
// crown_gear(mod=1, teeth=32, backing=3, face_width=7);
// color("lightblue")
// back(pitch_radius(mod=1,teeth=32)+7/2)
// up(gear_dist(mod=1,teeth1=0,teeth2=9))spur_gear(mod=1, teeth=9,orient=BACK,thickness=7,gear_spin=360/9/2);
// Continues:
// When constructing a crown gear you need to make it with the same given pressure and and tooth size as
// the spur gear you wish to mate to it. However, the teeth of a crown gear have pressure angle that varies
// along the width of the tooth. The vertical separation of the spur gear from the crown gear is given
// by {{gear_dist()}} where you treat the crown gear as a rack. The inner radius of the teeth on the
// crown gear is the pitch radius determined by the gear's tooth size and number of teeth. The face width
// of a crown gear is limited by geometry, so if you make it too large you will get an error.
// .
// Note that the geometry of these crown gears is tricky and not well documented by sources we have found.
// If you know something about crown gears that could improve the implementation, please open an issue
// on github.
// Section: Backlash (Fitting Real Gears Together)
// You may have noticed that the example gears shown fit together perfectly, making contact on both sides of
// the teeth. Real gears need space between the teeth to prevent the gears from jamming, to provide space
// for lubricant, and to provide allowance for fabrication error. This space is called backlash. Excessive backlash
// is undesirable, especially if the drive reverses frequently.
// .
// Backlash can be introduced in two ways. One is to make the teeth narrower, so the gaps between the teeth are
// larger than the teeth. Alternatively, you can move the gears farther apart than their ideal spacing.
// Backlash can be measured in several different ways. The gear modules in this library accept a backlash
// parameter which specifies backlash as a circular distance at the pitch circle. The modules narrow
// the teeth by the amount specified, which means the spaces between the teeth grow larger. Of course, if you apply
// backlash to both gears then the total backlash in the system is the combined amount from both gears.
// Usually it is best to apply backlash symmetrically to both gears, but if one gear is very small it may
// be better to place the backlash entirely on the larger gear to avoid weakening the teeth of the small gear.
// Figure(2D,Big,VPT=[4.5244,64.112,0.0383045],VPR=[0,0,0],VPD=48.517,NoAxes): Backlash narrows the teeth by the specified length along the pitch circle. Below the ideal gear appears in the lighter color and the darker color shows the same gear with a very large backlash, which appears with half of the backlash on either side of the tooth.
// teeth1=20;
// mod=5;
// r1 = pitch_radius(mod=mod,teeth=teeth1,helical=40);
// bang=4/(2*PI*r1) * 360 ;
// zrot(-180/teeth1*.5){
// color("white")
// dashed_stroke(arc(r=r1, n=30, angle=[80,110]), width=.05);
// spur_gear2d(mod=mod, teeth=teeth1,backlash=0+.5*0,profile_shift="auto",gear_spin=180/teeth1*.5,helical=40);
// %spur_gear2d(mod=mod, teeth=teeth1,backlash=4+.5*0,profile_shift="auto",gear_spin=180/teeth1*.5,helical=40);
// color("black")stroke(arc(n=32,r=r1,angle=[90+bang/2,90]),width=.1,endcaps="arrow2");
// }
// color("black")back(r1+.25)right(5.5)text("backlash/2",size=1);
// Figure(2D,Med,VPT=[0.532987,50.0891,0.0383045],VPR=[0,0,0],VPD=53.9078): Here two gears appear together with a more reasonable backlash applied to both gears. Again the lighter color shows the ideal gears and the darker shade shows the gear with backlash. Note that in this example, backlash is present on both of the meshing gears, so the total backlash of the system is the combined backlash from both gears.
// teeth1=20;teeth2=33;
// mod=5;
// ha=0;
// r1 = pitch_radius(mod=mod,teeth=teeth1,helical=ha);
// r2=pitch_radius(mod=mod,teeth=teeth2,helical=ha);
// bang=4/(2*PI*r1) * 360 ;
//
// back(r1+pitch_radius(mod=mod,teeth=teeth2,helical=ha)){
// spur_gear2d(mod=mod, teeth=teeth2,backlash=.5*0,helical=ha,gear_spin=-180/teeth2/2);
// %spur_gear2d(mod=mod, teeth=teeth2,backlash=1,helical=ha,gear_spin=-180/teeth2/2);
// }
// {
// spur_gear2d(mod=mod, teeth=teeth1,backlash=0+.5*0,profile_shift=0,gear_spin=180/teeth1*.5,helical=ha);
// %spur_gear2d(mod=mod, teeth=teeth1,backlash=1+.5*0,profile_shift=0,gear_spin=180/teeth1*.5,helical=ha);
// *color("white"){
// dashed_stroke(arc(r=r1, n=30, angle=[80,110]), width=.05);
// back(r1+r2)
// dashed_stroke(arc(r=r2, n=30, angle=[-80,-110]), width=.05);
// }
// //color("black")stroke(arc(n=32,r=r1,angle=[90+bang/2,90]),width=.1,endcaps="arrow2");
// }
// Figure(2D,Med,VPT=[0.532987,50.0891,0.0383045],VPR=[0,0,0],VPD=53.9078): Here the same gears as in the previous figure appear with backlash applied using the `backlash` parameter to {{gear_dist()}} to shift them apart. The original ideal gears are in the lighter shade and the darker colored gears have been separated to create the backlash.
// teeth1=20;teeth2=33;
// mod=5;
// ha=0;
// r1 = pitch_radius(mod=mod,teeth=teeth1,helical=ha);
// r2 = pitch_radius(mod=mod,teeth=teeth2,helical=ha);
// bang=4/(2*PI*r1) * 360 ;
// shift = 1 * cos(ha)/2/tan(20);
// back(r1+pitch_radius(mod=mod,teeth=teeth2,helical=ha)){
// zrot(-180/teeth2/2){
// %back(shift)spur_gear2d(mod=mod, teeth=teeth2,backlash=0,helical=ha);
// spur_gear2d(mod=mod, teeth=teeth2,backlash=0,helical=ha);
// }
// }
// zrot(180/teeth1*.5){
// %fwd(shift)spur_gear2d(mod=mod, teeth=teeth1,backlash=0+.5*0,profile_shift=0,helical=ha);
// spur_gear2d(mod=mod, teeth=teeth1,backlash=0,profile_shift=0,helical=ha);
// }
// Section: Gears
// Function&Module: spur_gear()
// Synopsis: Creates a spur gear, helical gear, or internal ring gear.
// SynTags: Geom, VNF
// Topics: Gears, Parts
// See Also: rack(), spur_gear(), spur_gear2d(), bevel_gear()
// Usage: As a Module
// spur_gear(circ_pitch, teeth, [thickness], [helical=], [pressure_angle=], [profile_shift=], [backlash=], [shaft_diam=], [hide=], [clearance=], [slices=], [internal=], [herringbone=]) [ATTACHMENTS];
// spur_gear(mod=|diam_pitch=, teeth=, [thickness=], ...) [ATTACHMENTS];
// Usage: As a Function
// vnf = spur_gear(circ_pitch, teeth, [thickness], ...);
// vnf = spur_gear(mod=|diam_pitch=, teeth=, [thickness=], ...);
// Description:
// Creates a involute spur gear, helical gear, herringbone gear, or a mask for an internal ring gear.
// For more information about gears, see [A Quick Introduction to Gears](gears.scad#section-a-quick-introduction-to-gears).
// You must specify the teeth size using either `mod=`, `circ_pitch=` or `diam_pitch=`, and you
// must give the number of teeth of the gear. 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.
// .
// The module creates the gear in the XY plane, centered on the origin, with one tooth centered on the positive Y axis.
// In order for two gears to mesh they must have the same tooth size and `pressure_angle`, and
// generally the helical angles should be of opposite sign.
// The usual pressure angle (and default) is 20 degrees. Another common value is 14.5 degrees.
// Ideally the teeth count of two meshing gears will be relatively prime because this ensures that
// every tooth on one gear will meet every tooth on the other, creating even wear.
// .
// The "pitch circle" of the gear is a reference circle where the circular pitch is defined that
// is used to construct the gear. It runs approximately through the centers of the teeth.
// Two basic gears will mesh when their pitch circles are tangent. Anchoring for these gears is
// done on the pitch circle by default, so basic gears can be meshed using anchoring.
// However, when a gear has a small number of teeth, the basic gear form will result in undercutting,
// which weakens the teeth. To avoid this, profile shifting is automatically applied and in this
// case, the distance between the gears is a complicated calculation and must be determined using {{gear_dist()}}.
// If you wish to override this correction, you can use `profile_shift=0`, or set it to a specific
// value like 0.5. Another complication with profile shifted gears is that the tips may be too long,
// which can eat into the clearance space. To address this problem you can use the `shorten` parameter,
// which you can compute using {{gear_shorten()}}.
// .
// Helical gears can mesh with skew or crossed axes, a configuration sometimes called "screw gears".
// Without profile shifting, that angle is the sum of the helical angles.
// With profile shifting it is slightly different and is given by {{gear_skew_angle()}}.
// These gears still mesh on the pitch circle when they are not profile shifted, but the correction to
// gear separation for a proper mesh of profile shifted gears is different for skew gears and is
// computed using {{gear_dist_skew()}}.
// .
// To create space for gears to mesh in practice you will need to set a positive value for backlash, or
// use the `backlash` argument to {{gear_dist()}}.
// Arguments:
// circ_pitch = The circular pitch, the distance between teeth centers around the pitch circle.
// teeth = Total number of teeth around the entire perimeter
// thickness = Thickness of gear. Default: 10
// ---
// mod = The module of the gear (pitch diameter / teeth)
// 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.
// helical = Teeth spiral around the gear at this angle, positive for left handed, negative for right handed. Default: 0
// herringbone = If true, and helical is set, creates a herringbone gear. Default: False
// pressure_angle = Controls how straight or bulged the tooth sides are. In degrees. Default: 20
// profile_shift = Profile shift factor x. Default: "auto"
// shorten = Shorten gear tips by the module times this value. Needed for large profile shifted gears. Default: 0
// backlash = Gap between two meshing teeth, in the direction along the circumference of the pitch circle. Default: 0
// shaft_diam = Diameter of the hole in the center. Default: 0 (no shaft hole)
// hide = Number of teeth to delete to make this only a fraction of a circle. Default: 0
// gear_spin = Rotate gear and children around the gear center, regardless of how gear is anchored. Default: 0
// clearance = Clearance gap at the bottom of the inter-tooth valleys. Default: mod/4
// slices = Number of vertical layers to divide gear into. Useful for refining gears with `helical`.
// internal = If true, create a mask for difference()ing from something else.
// atype = Set to "root", "tip" or "pitch" to determine anchoring circle. Default: "pitch"
// 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"
// Anchor Types:
// root = anchor on the root circle
// pitch = anchor on the pitch circle (default)
// tip = anchor on the tip circle
// Example: Spur Gear
// spur_gear(circ_pitch=5, teeth=20, thickness=8, shaft_diam=5);
// 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,
// 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
// );
// Example(Med,VPT=[-0.0213774,2.42972,-0.2709],VPR=[36.1,0,20.1],VPD=74.3596): 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;
// d = gear_dist(circ_pitch=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, orient=BACK);
// color("black") up(thick/2) linear_extrude(height=0.1) {
// 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;
// d = gear_dist(circ_pitch=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, orient=BACK);
// color("black") up(thick/2) linear_extrude(height=0.1) {
// back(d)
// dashed_stroke(circle(r=pr), width=strokewidth, closed=true);
// dashed_stroke([[-7.5,0],[7.5,0]], width=strokewidth);
// }
// }
// Example(Anim,Med,NoAxes,Frames=8,VPT=[0,30,0],VPR=[0,0,0],VPD=300): Assembly of Gears
// $fn=12;
// n1 = 11; //red gear number of teeth
// n2 = 20; //green gear
// n3 = 6; //blue gear
// n4 = 16; //orange gear
// n5 = 9; //gray rack
// circ_pitch = 9; //all meshing gears need the same `circ_pitch` (and the same `pressure_angle`)
// thickness = 6;
// hole = 3;
// rack_base = 12;
// d12 = gear_dist(circ_pitch=circ_pitch,teeth1=n1,teeth2=n2);
// d13 = gear_dist(circ_pitch=circ_pitch,teeth1=n1,teeth2=n3);
// d14 = gear_dist(circ_pitch=circ_pitch,teeth1=n1,teeth2=n4);
// d1r = gear_dist(circ_pitch=circ_pitch,teeth1=n1,teeth2=0);
// 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);
// 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,width=rack_base,anchor=CENTER,orient=BACK);
// Example(NoAxes,VPT=[1.13489,-4.48517,1.04995],VPR=[55,0,25],VPD=139.921): Helical gears meshing with non-parallel shafts
// ang1 = 30;
// ang2 = 10;
// circ_pitch = 5;
// n = 20;
// dist = gear_dist_skew(
// circ_pitch=circ_pitch,
// teeth1=n, teeth2=n,
// helical1=ang1, helical2=ang2);
// left(dist/2) spur_gear(
// circ_pitch, teeth=n, thickness=10,
// shaft_diam=5, helical=ang1, slices=12,
// gear_spin=-90
// );
// right(dist/2)
// 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,Big,NoAxes,Frames=36,VPT=[0,0,0],VPR=[55,0,25],VPD=220): Planetary Gear Assembly
// $fn=128;
// rteeth=56; pteeth=16; cteeth=24;
// circ_pitch=5; thick=10; pa=20;
// gd = gear_dist(circ_pitch=circ_pitch, cteeth, pteeth);
// ring_gear(
// circ_pitch=circ_pitch,
// teeth=rteeth,
// thickness=thick,
// pressure_angle=pa);
// for (a=[0:3]) {
// 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);
function spur_gear(
circ_pitch,
teeth,
thickness,
shaft_diam = 0,
hide = 0,
pressure_angle,
clearance,
backlash = 0.0,
helical,
interior,
internal,
profile_shift="auto",
slices,
herringbone=false,
shorten=0,
diam_pitch,
mod,
pitch,
gear_spin = 0,
atype = "pitch",
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)
)
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(gear_spin))
let(
profile_shift = auto_profile_shift(teeth,PA,helical,profile_shift=profile_shift),
pr = pitch_radius(circ_pitch, teeth, helical),
or = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=internal,shorten=shorten),
rr = _root_radius(circ_pitch, teeth, clearance, profile_shift=profile_shift, internal=internal),
anchor_rad = atype=="pitch" ? pr
: atype=="tip" ? or
: atype=="root" ? rr
: assert(false,"atype must be one of \"root\", \"tip\" or \"pitch\""),
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,
teeth = teeth,
pressure_angle = PA,
hide = hide,
helical = helical,
clearance = clearance,
backlash = backlash,
internal = internal,
shorten = shorten,
profile_shift = profile_shift,
shaft_diam = shaft_diam
),
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=anchor_rad, p=vnf);
module spur_gear(
circ_pitch,
teeth,
thickness,
shaft_diam = 0,
hide = 0,
pressure_angle,
clearance,
backlash = 0.0,
helical,
internal,
interior,
profile_shift="auto",
slices,
herringbone=false,
shorten=0,
pitch,
diam_pitch,
mod,
atype="pitch",
gear_spin = 0,
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);
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))