designix 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/.eslintignore +17 -0
  2. package/.eslintrc.cjs +24 -0
  3. package/.prettierignore +15 -0
  4. package/.prettierrc +8 -0
  5. package/README.md +27 -0
  6. package/export_svg/base.svg +1 -0
  7. package/export_svg/base_cut.svg +1 -0
  8. package/export_svg/base_hollow.svg +1 -0
  9. package/export_svg/base_top.svg +1 -0
  10. package/export_svg/calculation_of_initAngle2.svg +1 -0
  11. package/export_svg/circles.svg +1 -0
  12. package/export_svg/circles_amplitude-offset.svg +1 -0
  13. package/export_svg/circles_amplitude-scale.svg +1 -0
  14. package/export_svg/circles_angle.svg +1 -0
  15. package/export_svg/default_param_blank.svg +1 -0
  16. package/export_svg/dummy_pole_static.svg +1 -0
  17. package/export_svg/dummy_pole_static_face.svg +1 -0
  18. package/export_svg/gear_addendeum_dedendum_sizes.svg +9 -0
  19. package/export_svg/gear_addendum_and_dedendum.svg +1 -0
  20. package/export_svg/gear_adherence_replaced_by_teeth.svg +1 -0
  21. package/export_svg/gear_base_circle_for_involute.svg +2 -0
  22. package/export_svg/gear_base_left_circle_for_involute.svg +2 -0
  23. package/export_svg/gear_base_right_circle_for_involute.svg +2 -0
  24. package/export_svg/gear_inter_axis_maximum_distance.svg +1 -0
  25. package/export_svg/gear_inter_axis_minimum_distance.svg +1 -0
  26. package/export_svg/gear_large_base_radius.svg +5 -0
  27. package/export_svg/gear_module_and_tooth_thickness.svg +3 -0
  28. package/export_svg/gear_optimum_base_radius.svg +5 -0
  29. package/export_svg/gear_optimum_base_radius_with_longer_inter_axis.svg +5 -0
  30. package/export_svg/gear_right_left_base_circles.svg +1 -0
  31. package/export_svg/gear_small_base_radius.svg +5 -0
  32. package/export_svg/gear_wheel_circles.svg +2 -0
  33. package/export_svg/gears.svg +71 -0
  34. package/export_svg/gears_motion_transmission_via_adherence.svg +1 -0
  35. package/export_svg/heliostat.svg +1 -0
  36. package/export_svg/heliostat2_face_sizing.svg +1 -0
  37. package/export_svg/heliostat2_side_sizing.svg +1 -0
  38. package/export_svg/heliostat_face_sizing.svg +1 -0
  39. package/export_svg/heliostat_overview.svg +1 -0
  40. package/export_svg/heliostat_side.svg +1 -0
  41. package/export_svg/heliostat_side_sizing.svg +1 -0
  42. package/export_svg/involute_of_circle.svg +19 -0
  43. package/export_svg/involute_of_circle_R0.svg +1 -0
  44. package/export_svg/involute_of_circle_Ri1_u0.svg +1 -0
  45. package/export_svg/involute_of_circle_Ri2_u2.svg +1 -0
  46. package/export_svg/left_side_angle_kitchen.svg +1 -0
  47. package/export_svg/negative_involute_of_circle_R0.svg +1 -0
  48. package/export_svg/point_c_position_and_speed_negative.svg +1 -0
  49. package/export_svg/point_c_position_and_speed_positive.svg +1 -0
  50. package/export_svg/pole_rotor.svg +1 -0
  51. package/export_svg/pole_rotor_cut.svg +1 -0
  52. package/export_svg/pole_rotor_ends.svg +1 -0
  53. package/export_svg/pole_stator.svg +3 -0
  54. package/export_svg/pole_stator_E2.svg +3 -0
  55. package/export_svg/pole_stator_bottom.svg +1 -0
  56. package/export_svg/pole_stator_cut.svg +1 -0
  57. package/export_svg/pole_stator_face.svg +1 -0
  58. package/export_svg/pole_stator_right.svg +1 -0
  59. package/export_svg/rake.svg +1 -0
  60. package/export_svg/rake_door.svg +1 -0
  61. package/export_svg/rake_face.svg +1 -0
  62. package/export_svg/rake_side.svg +1 -0
  63. package/export_svg/rake_side_stopper.svg +1 -0
  64. package/export_svg/rake_top.svg +1 -0
  65. package/export_svg/rake_top_stopper.svg +1 -0
  66. package/export_svg/rectangle.svg +1 -0
  67. package/export_svg/rectangle_height.svg +1 -0
  68. package/export_svg/rectangle_width.svg +1 -0
  69. package/export_svg/right_side_angle_kitchen.svg +1 -0
  70. package/export_svg/rod.svg +1 -0
  71. package/export_svg/rod_cut.svg +1 -0
  72. package/export_svg/rod_plate.svg +1 -0
  73. package/export_svg/rod_top.svg +1 -0
  74. package/export_svg/spider.svg +1 -0
  75. package/export_svg/spider_lateral.svg +1 -0
  76. package/export_svg/spider_profile.svg +1 -0
  77. package/export_svg/surface.svg +3 -0
  78. package/export_svg/surface_crenel.svg +1 -0
  79. package/export_svg/surface_extremities.svg +2 -0
  80. package/export_svg/surface_lz.svg +1 -0
  81. package/export_svg/surface_main.svg +1 -0
  82. package/export_svg/surface_power.svg +2 -0
  83. package/export_svg/surface_space_evolution.svg +1 -0
  84. package/export_svg/surface_space_shape.svg +1 -0
  85. package/export_svg/swing.svg +1 -0
  86. package/export_svg/swing_face.svg +1 -0
  87. package/export_svg/swing_side.svg +1 -0
  88. package/export_svg/swing_top.svg +1 -0
  89. package/export_svg/swing_with_rod.svg +1 -0
  90. package/export_svg/trapeze.svg +1 -0
  91. package/export_svg/trapeze_rod.svg +1 -0
  92. package/export_svg/trapeze_side.svg +1 -0
  93. package/export_svg/trapeze_top.svg +1 -0
  94. package/export_svg/verify_contour_1.svg +1 -0
  95. package/export_svg/verify_contour_1_l1.svg +1 -0
  96. package/export_svg/verify_contour_1_r1.svg +1 -0
  97. package/export_svg/verify_line.svg +1 -0
  98. package/export_svg/verify_line_2_l1cx.svg +1 -0
  99. package/export_svg/verify_line_p1x.svg +1 -0
  100. package/export_svg/verify_point.svg +1 -0
  101. package/export_svg/verify_point_p1x.svg +1 -0
  102. package/export_svg/verify_vector_p1x.svg +1 -0
  103. package/package.json +76 -0
  104. package/src/dummy/circles.ts +65 -0
  105. package/src/dummy/pole_static.ts +86 -0
  106. package/src/dummy/rectangle.ts +55 -0
  107. package/src/dummy/svg/circles.svg +288 -0
  108. package/src/dummy/svg/circles_amplitude-offset.svg +109 -0
  109. package/src/dummy/svg/circles_amplitude-scale.svg +122 -0
  110. package/src/dummy/svg/circles_angle.svg +110 -0
  111. package/src/dummy/svg/dummy_pole_static.svg +192 -0
  112. package/src/dummy/svg/dummy_pole_static_face.svg +176 -0
  113. package/src/dummy/svg/rectangle.svg +131 -0
  114. package/src/dummy/svg/rectangle_height.svg +82 -0
  115. package/src/dummy/svg/rectangle_width.svg +81 -0
  116. package/src/gears/gearWheelProfile.test.ts +25 -0
  117. package/src/gears/gearWheelProfile.ts +753 -0
  118. package/src/gears/gear_wheel_wheel.ts +335 -0
  119. package/src/gears/involute.test.ts +21 -0
  120. package/src/gears/involute.ts +113 -0
  121. package/src/gears/simplified_gear_wheel.ts +242 -0
  122. package/src/gears/svg/calculation_of_initAngle2.svg +376 -0
  123. package/src/gears/svg/gear_addendeum_dedendum_sizes.svg +471 -0
  124. package/src/gears/svg/gear_addendum_and_dedendum.svg +269 -0
  125. package/src/gears/svg/gear_adherence_replaced_by_teeth.svg +168 -0
  126. package/src/gears/svg/gear_base_circle_for_involute.svg +376 -0
  127. package/src/gears/svg/gear_base_left_circle_for_involute.svg +556 -0
  128. package/src/gears/svg/gear_base_right_circle_for_involute.svg +516 -0
  129. package/src/gears/svg/gear_inter_axis_maximum_distance.svg +218 -0
  130. package/src/gears/svg/gear_inter_axis_minimum_distance.svg +218 -0
  131. package/src/gears/svg/gear_large_base_radius.svg +199 -0
  132. package/src/gears/svg/gear_module_and_tooth_thickness.svg +319 -0
  133. package/src/gears/svg/gear_optimum_base_radius.svg +232 -0
  134. package/src/gears/svg/gear_optimum_base_radius_with_longer_inter_axis.svg +344 -0
  135. package/src/gears/svg/gear_right_left_base_circles.svg +295 -0
  136. package/src/gears/svg/gear_small_base_radius.svg +163 -0
  137. package/src/gears/svg/gear_wheel_circles.svg +348 -0
  138. package/src/gears/svg/gears.svg +4726 -0
  139. package/src/gears/svg/gears_motion_transmission_via_adherence.svg +178 -0
  140. package/src/gears/svg/involute_of_circle.svg +2745 -0
  141. package/src/gears/svg/involute_of_circle_R0.svg +334 -0
  142. package/src/gears/svg/involute_of_circle_Ri1_u0.svg +297 -0
  143. package/src/gears/svg/involute_of_circle_Ri2_u2.svg +386 -0
  144. package/src/gears/svg/left_side_angle_kitchen.svg +207 -0
  145. package/src/gears/svg/negative_involute_of_circle_R0.svg +381 -0
  146. package/src/gears/svg/point_c_position_and_speed_negative.svg +343 -0
  147. package/src/gears/svg/point_c_position_and_speed_positive.svg +339 -0
  148. package/src/gears/svg/right_side_angle_kitchen.svg +201 -0
  149. package/src/gears/wheelElements.test.ts +13 -0
  150. package/src/gears/wheelElements.ts +176 -0
  151. package/src/geometrix_verification/svg/verify_contour_1.svg +320 -0
  152. package/src/geometrix_verification/svg/verify_contour_1_l1.svg +102 -0
  153. package/src/geometrix_verification/svg/verify_contour_1_r1.svg +170 -0
  154. package/src/geometrix_verification/svg/verify_line.svg +845 -0
  155. package/src/geometrix_verification/svg/verify_line_2_l1cx.svg +274 -0
  156. package/src/geometrix_verification/svg/verify_line_p1x.svg +261 -0
  157. package/src/geometrix_verification/svg/verify_point.svg +350 -0
  158. package/src/geometrix_verification/svg/verify_point_p1x.svg +258 -0
  159. package/src/geometrix_verification/svg/verify_vector_p1x.svg +282 -0
  160. package/src/geometrix_verification/verify_contour_1.ts +94 -0
  161. package/src/geometrix_verification/verify_contour_2.ts +267 -0
  162. package/src/geometrix_verification/verify_contour_3.ts +409 -0
  163. package/src/geometrix_verification/verify_contour_4.ts +91 -0
  164. package/src/geometrix_verification/verify_exports_1.ts +95 -0
  165. package/src/geometrix_verification/verify_line.ts +76 -0
  166. package/src/geometrix_verification/verify_line_2.ts +76 -0
  167. package/src/geometrix_verification/verify_line_3.ts +64 -0
  168. package/src/geometrix_verification/verify_point.ts +62 -0
  169. package/src/geometrix_verification/verify_point_2.ts +66 -0
  170. package/src/geometrix_verification/verify_vector.ts +70 -0
  171. package/src/heliostat/base.ts +254 -0
  172. package/src/heliostat/heliostat.ts +317 -0
  173. package/src/heliostat/heliostat_2.ts +284 -0
  174. package/src/heliostat/pole_rotor.ts +165 -0
  175. package/src/heliostat/pole_static.ts +275 -0
  176. package/src/heliostat/rake.ts +486 -0
  177. package/src/heliostat/rake_stopper.ts +409 -0
  178. package/src/heliostat/rod.ts +200 -0
  179. package/src/heliostat/spider.ts +238 -0
  180. package/src/heliostat/surface.ts +320 -0
  181. package/src/heliostat/svg/base.svg +1367 -0
  182. package/src/heliostat/svg/base_cut.svg +459 -0
  183. package/src/heliostat/svg/base_hollow.svg +469 -0
  184. package/src/heliostat/svg/base_top.svg +338 -0
  185. package/src/heliostat/svg/heliostat.svg +8013 -0
  186. package/src/heliostat/svg/heliostat2_face_sizing.svg +1386 -0
  187. package/src/heliostat/svg/heliostat2_side_sizing.svg +984 -0
  188. package/src/heliostat/svg/heliostat_face_sizing.svg +1448 -0
  189. package/src/heliostat/svg/heliostat_overview.svg +1552 -0
  190. package/src/heliostat/svg/heliostat_side.svg +1470 -0
  191. package/src/heliostat/svg/heliostat_side_sizing.svg +1128 -0
  192. package/src/heliostat/svg/pole_rotor.svg +592 -0
  193. package/src/heliostat/svg/pole_rotor_cut.svg +287 -0
  194. package/src/heliostat/svg/pole_rotor_ends.svg +336 -0
  195. package/src/heliostat/svg/pole_stator.svg +1945 -0
  196. package/src/heliostat/svg/pole_stator_E2.svg +410 -0
  197. package/src/heliostat/svg/pole_stator_bottom.svg +330 -0
  198. package/src/heliostat/svg/pole_stator_cut.svg +465 -0
  199. package/src/heliostat/svg/pole_stator_face.svg +457 -0
  200. package/src/heliostat/svg/pole_stator_right.svg +357 -0
  201. package/src/heliostat/svg/rake.svg +4691 -0
  202. package/src/heliostat/svg/rake_door.svg +617 -0
  203. package/src/heliostat/svg/rake_face.svg +1211 -0
  204. package/src/heliostat/svg/rake_side.svg +809 -0
  205. package/src/heliostat/svg/rake_side_stopper.svg +596 -0
  206. package/src/heliostat/svg/rake_top.svg +514 -0
  207. package/src/heliostat/svg/rake_top_stopper.svg +565 -0
  208. package/src/heliostat/svg/rod.svg +1314 -0
  209. package/src/heliostat/svg/rod_cut.svg +265 -0
  210. package/src/heliostat/svg/rod_plate.svg +409 -0
  211. package/src/heliostat/svg/rod_top.svg +577 -0
  212. package/src/heliostat/svg/spider.svg +693 -0
  213. package/src/heliostat/svg/spider_lateral.svg +222 -0
  214. package/src/heliostat/svg/spider_profile.svg +429 -0
  215. package/src/heliostat/svg/surface.svg +3577 -0
  216. package/src/heliostat/svg/surface_crenel.svg +1335 -0
  217. package/src/heliostat/svg/surface_extremities.svg +510 -0
  218. package/src/heliostat/svg/surface_lz.svg +182 -0
  219. package/src/heliostat/svg/surface_main.svg +366 -0
  220. package/src/heliostat/svg/surface_power.svg +331 -0
  221. package/src/heliostat/svg/surface_space_evolution.svg +210 -0
  222. package/src/heliostat/svg/surface_space_shape.svg +98 -0
  223. package/src/heliostat/svg/swing.svg +3310 -0
  224. package/src/heliostat/svg/swing_face.svg +902 -0
  225. package/src/heliostat/svg/swing_side.svg +574 -0
  226. package/src/heliostat/svg/swing_top.svg +923 -0
  227. package/src/heliostat/svg/swing_with_rod.svg +547 -0
  228. package/src/heliostat/svg/trapeze.svg +1711 -0
  229. package/src/heliostat/svg/trapeze_rod.svg +122 -0
  230. package/src/heliostat/svg/trapeze_side.svg +361 -0
  231. package/src/heliostat/svg/trapeze_top.svg +1057 -0
  232. package/src/heliostat/swing.ts +246 -0
  233. package/src/heliostat/trapeze.ts +510 -0
  234. package/src/index.ts +33 -0
  235. package/src/svg/default_param_blank.svg +40 -0
  236. package/tsconfig.json +13 -0
  237. package/vitest.config.ts +7 -0
@@ -0,0 +1,753 @@
1
+ // gearWheelProfile.ts
2
+
3
+ import type { Point, tContour } from 'geometrix';
4
+ import {
5
+ contour,
6
+ contourCircle,
7
+ point,
8
+ ShapePoint,
9
+ lcFromLaLbAc,
10
+ aBFromLaLbAa,
11
+ withinZero2Pi,
12
+ withinPiPi,
13
+ radToDeg,
14
+ roundZero,
15
+ ffix
16
+ } from 'geometrix';
17
+ import type { Involute } from './involute';
18
+ import { involute } from './involute';
19
+
20
+ class GearWheelProfile {
21
+ mod = 1;
22
+ TN = 23;
23
+ as = 1;
24
+ cx = 0;
25
+ cy = 0;
26
+ brr = 50;
27
+ blr = 50;
28
+ ar = 54;
29
+ pr = 53;
30
+ dr = 52;
31
+ br = 51;
32
+ bRound = 1;
33
+ adt = 0.5;
34
+ initAngle = 0;
35
+ axisAngle = 0;
36
+ involArcPairs = 1;
37
+ skinThickness = 0;
38
+ involuteR = involute(0, 0, 50, 0, true);
39
+ involuteL = involute(0, 0, 50, 0, false);
40
+ rud = 0;
41
+ rup = 0;
42
+ rua = 0;
43
+ rwd = 0;
44
+ rwp = 0;
45
+ rwa = 0;
46
+ lud = 0;
47
+ lup = 0;
48
+ lua = 0;
49
+ lwd = 0;
50
+ lwp = 0;
51
+ lwa = 0;
52
+ msg: string;
53
+ initStep = 0;
54
+ constructor() {
55
+ this.mod = 1;
56
+ this.msg = '';
57
+ this.initStep = 0;
58
+ }
59
+ incInitStep(target: number) {
60
+ if (this.initStep + 1 !== target) {
61
+ throw `err834: incInitStep initStep ${this.initStep} and target ${target} are not compatible`;
62
+ }
63
+ this.initStep = target;
64
+ }
65
+ checkInitStep(targetMin: number, msg: string) {
66
+ if (this.initStep < targetMin) {
67
+ throw `err835: checkInitStep for ${msg} initStep ${this.initStep} is too small compare to targetMin ${targetMin}`;
68
+ }
69
+ }
70
+ set1ModuleToothNumber(iMod: number, iTN: number) {
71
+ this.incInitStep(1);
72
+ this.mod = iMod;
73
+ this.TN = iTN;
74
+ this.pr = (this.mod * this.TN) / 2;
75
+ this.as = (2 * Math.PI) / this.TN;
76
+ }
77
+ set2CenterPosition(icx: number, icy: number) {
78
+ this.incInitStep(2);
79
+ this.cx = icx;
80
+ this.cy = icy;
81
+ }
82
+ set3CircleRadius(iah: number, idh: number, ibh: number, ibRound: number) {
83
+ this.incInitStep(3);
84
+ this.ar = this.pr + this.mod * iah;
85
+ this.dr = this.pr - this.mod * idh;
86
+ this.br = this.dr - this.mod * ibh;
87
+ this.bRound = ibRound;
88
+ }
89
+ set4BaseCircles(baseRight: number, baseLeft: number) {
90
+ this.incInitStep(4);
91
+ this.brr = baseRight;
92
+ this.blr = baseLeft;
93
+ }
94
+ set5AddendumThickness(iat: number) {
95
+ this.incInitStep(5);
96
+ this.adt = iat / 100;
97
+ }
98
+ set6Angles(initAng: number, axisAng: number) {
99
+ this.incInitStep(6);
100
+ this.initAngle = initAng;
101
+ this.axisAngle = axisAng;
102
+ }
103
+ set7InvoluteDetails(iInvolArcPairs: number, iSkinThickness: number) {
104
+ this.incInitStep(7);
105
+ this.involArcPairs = iInvolArcPairs;
106
+ this.skinThickness = iSkinThickness;
107
+ }
108
+ getRefCircles(): tContour[] {
109
+ this.checkInitStep(4, 'getRefCircles');
110
+ const rRefCircles = [
111
+ contourCircle(this.cx, this.cy, this.ar, 'Azure'),
112
+ contourCircle(this.cx, this.cy, this.pr, 'Azure'),
113
+ contourCircle(this.cx, this.cy, this.dr, 'Azure'),
114
+ contourCircle(this.cx, this.cy, this.br, 'Azure'),
115
+ contourCircle(this.cx, this.cy, this.brr, 'CornFlowerBlue'),
116
+ contourCircle(this.cx, this.cy, this.blr, 'Crimson')
117
+ ];
118
+ return rRefCircles;
119
+ }
120
+ calcInvoluteAngles() {
121
+ this.checkInitStep(4, 'calcInvoluteAngles');
122
+ this.involuteR = involute(this.cx, this.cy, this.brr, 0, true);
123
+ if (this.dr > this.brr) {
124
+ this.rud = this.involuteR.uFromL(this.dr);
125
+ } else {
126
+ this.rud = 0;
127
+ }
128
+ this.rup = this.involuteR.uFromL(this.pr);
129
+ this.rua = this.involuteR.uFromL(this.ar);
130
+ this.rwd = this.involuteR.wFromU(this.rud);
131
+ this.rwp = this.involuteR.wFromU(this.rup);
132
+ this.rwa = this.involuteR.wFromU(this.rua);
133
+ this.involuteL = involute(this.cx, this.cy, this.blr, 0, false);
134
+ if (this.dr > this.blr) {
135
+ this.lud = this.involuteL.uFromL(this.dr);
136
+ } else {
137
+ this.rud = 0;
138
+ }
139
+ this.lup = this.involuteL.uFromL(this.pr);
140
+ this.lua = this.involuteL.uFromL(this.ar);
141
+ this.lwd = this.involuteL.wFromU(this.lud);
142
+ this.lwp = this.involuteL.wFromU(this.lup);
143
+ this.lwa = this.involuteL.wFromU(this.lua);
144
+ }
145
+ checkProfileConditions() {
146
+ const aas = this.as * this.adt;
147
+ const rwpa = this.rwa - this.rwp;
148
+ const lwpa = Math.abs(this.lwa - this.lwp);
149
+ //this.msg += `dbg10_: rwa ${ffix(this.rwa)} rwp ${ffix(this.rwp)}\n`;
150
+ //this.msg += `dbg109: lwa ${ffix(this.lwa)} lwp ${ffix(this.lwp)}\n`;
151
+ //this.msg += `dbg110: aas ${ffix(aas)} rwpa ${ffix(rwpa)} lwpa ${ffix(lwpa)}\n`;
152
+ const aAddendum = aas - rwpa - lwpa;
153
+ if (aAddendum < 0) {
154
+ throw `err554: No remaining Addendum reserve ${ffix(aAddendum)}\n`;
155
+ }
156
+ const ads = this.as * (1 - this.adt);
157
+ const rwpd = this.rwp - this.rwd;
158
+ const lwpd = Math.abs(this.lwp - this.lwd);
159
+ const aDedendum = ads - rwpd - lwpd;
160
+ if (aDedendum < 2 * Math.atan2(this.bRound, this.br)) {
161
+ throw `err555: No remaining Dedendum reserve ${ffix(
162
+ aDedendum
163
+ )} compare to bRound ${ffix(this.bRound)}\n`;
164
+ }
165
+ }
166
+ getToothRef(): tContour {
167
+ const ptnb = 6 * this.involArcPairs;
168
+ const toothID = 0;
169
+ this.checkInitStep(7, 'getProfile');
170
+ this.calcInvoluteAngles();
171
+ const uPeriodR = (this.rua - this.rud) / ptnb;
172
+ const uPeriodL = (this.lua - this.lud) / ptnb;
173
+ const refA = this.initAngle + toothID * this.as;
174
+ const invoR = involute(this.cx, this.cy, this.brr, refA - this.rwp, true);
175
+ const [p1x, p1y] = invoR.ptc(this.rud + 0 * uPeriodR);
176
+ const rCtr = contour(p1x, p1y, 'Gold');
177
+ for (let j = 0; j < ptnb; j++) {
178
+ const [px, py] = invoR.ptc(this.rud + (j + 1) * uPeriodR);
179
+ rCtr.addSegStrokeA(px, py);
180
+ }
181
+ const refAl = refA + this.as * this.adt;
182
+ const invoL = involute(this.cx, this.cy, this.blr, refAl - this.lwp, false);
183
+ for (let j = 0; j < ptnb + 1; j++) {
184
+ const [px, py] = invoL.ptc(this.lud + (ptnb - j) * uPeriodL);
185
+ rCtr.addSegStrokeA(px, py);
186
+ }
187
+ rCtr.closeSegStroke();
188
+ return rCtr;
189
+ }
190
+ getProfile(): tContour {
191
+ this.checkInitStep(7, 'getProfile');
192
+ this.calcInvoluteAngles();
193
+ this.checkProfileConditions();
194
+ const aDiffRd = this.rwd - this.rwp;
195
+ //const aDiffRa = this.rwa - this.rwp;
196
+ const aDiffLd = this.lwd - this.lwp;
197
+ //const aDiffLa = this.lwa - this.lwp;
198
+ const erdr = this.dr > this.brr ? this.dr : this.brr;
199
+ const eldr = this.dr > this.blr ? this.dr : this.blr;
200
+ if (this.bRound > erdr - this.br) {
201
+ throw `err409: getProfile bRound ${ffix(this.bRound)} too large for erdr ${ffix(
202
+ erdr
203
+ )} and br ${ffix(this.br)}`;
204
+ }
205
+ if (this.bRound > eldr - this.br) {
206
+ throw `err408: getProfile bRound ${ffix(this.bRound)} too large for eldr ${ffix(
207
+ eldr
208
+ )} and br ${ffix(this.br)}`;
209
+ }
210
+ const uPeriodR = (this.rua - this.rud) / this.involArcPairs;
211
+ const uPeriodL = (this.lua - this.lud) / this.involArcPairs;
212
+ const center = point(this.cx, this.cy);
213
+ // this first point is equal to the first stroke of the loop.
214
+ // Contour will remove it because last and new points are identical
215
+ const first = center.translatePolar(this.initAngle + aDiffRd, this.br);
216
+ const rProfile = contour(first.cx, first.cy);
217
+ for (let i = 0; i < this.TN; i++) {
218
+ const refA = this.initAngle + i * this.as;
219
+ const ptrb = center.translatePolar(refA + aDiffRd, this.br);
220
+ rProfile.addSegStrokeA(ptrb.cx, ptrb.cy).addCornerRounded(this.bRound);
221
+ const invoR = involute(this.cx, this.cy, this.brr, refA - this.rwp, true);
222
+ //const ptrd = center.translatePolar(refA + aDiffRd, erdr);
223
+ const [px1, py1] = invoR.ptc(this.rud);
224
+ const ta11 = invoR.ptcta(this.rud);
225
+ const ptrd = point(px1, py1).translatePolar(ta11 - Math.PI / 2, this.skinThickness);
226
+ rProfile.addSegStrokeA(ptrd.cx, ptrd.cy);
227
+ //const ptrp = center.translatePolar(refA, this.pr);
228
+ //rProfile.addSegStrokeA(ptrp.cx, ptrp.cy);
229
+ //const ptra = center.translatePolar(refA + aDiffRa, this.ar);
230
+ //rProfile.addSegStrokeA(ptra.cx, ptra.cy);
231
+ for (let j = 0; j < this.involArcPairs; j++) {
232
+ const uu1 = this.rud + j * uPeriodR;
233
+ const [px, py] = invoR.ptc(uu1 + uPeriodR);
234
+ const ta1 = invoR.ptcta(uu1);
235
+ const ta2 = invoR.ptcta(uu1 + uPeriodR) + Math.PI;
236
+ const pn = point(px, py).translatePolar(ta1 - Math.PI / 2, this.skinThickness);
237
+ //rProfile.addSegStrokeA(px, py);
238
+ rProfile.addPointA(pn.cx, pn.cy).addSeg2Arcs(ta1, ta2);
239
+ }
240
+ const refAl = refA + this.as * this.adt;
241
+ const invoL = involute(this.cx, this.cy, this.blr, refAl - this.lwp, false);
242
+ //const ptla = center.translatePolar(refAl + aDiffLa, this.ar);
243
+ const uu2 = this.lud + this.involArcPairs * uPeriodL;
244
+ const [px2, py2] = invoL.ptc(uu2);
245
+ const ta12 = invoL.ptcta(uu2) + Math.PI;
246
+ const ptla = point(px2, py2).translatePolar(ta12 - Math.PI / 2, this.skinThickness);
247
+ rProfile.addSegStrokeA(ptla.cx, ptla.cy);
248
+ //const ptlp = center.translatePolar(refAl, this.pr);
249
+ //rProfile.addSegStrokeA(ptlp.cx, ptlp.cy);
250
+ //const ptld = center.translatePolar(refAl + aDiffLd, eldr);
251
+ //rProfile.addSegStrokeA(ptld.cx, ptld.cy);
252
+ for (let j = 0; j < this.involArcPairs; j++) {
253
+ const uu1 = this.lud + (this.involArcPairs - j) * uPeriodL;
254
+ const [px, py] = invoL.ptc(uu1 - uPeriodL);
255
+ const ta1 = invoL.ptcta(uu1) + Math.PI;
256
+ const ta2 = invoL.ptcta(uu1 - uPeriodL);
257
+ const pn = point(px, py).translatePolar(ta1 - Math.PI / 2, this.skinThickness);
258
+ //rProfile.addSegStrokeA(px, py);
259
+ rProfile.addPointA(pn.cx, pn.cy).addSeg2Arcs(ta1, ta2);
260
+ }
261
+ const ptlb = center.translatePolar(refAl + aDiffLd, this.br);
262
+ rProfile.addSegStrokeA(ptlb.cx, ptlb.cy).addCornerRounded(this.bRound);
263
+ }
264
+ rProfile.closeSegStroke();
265
+ return rProfile;
266
+ }
267
+ getMsg(): string {
268
+ return this.msg;
269
+ }
270
+ }
271
+
272
+ function gwProfile(): GearWheelProfile {
273
+ const rgwp = new GearWheelProfile();
274
+ return rgwp;
275
+ }
276
+
277
+ enum EInvolOpt {
278
+ Optimum = 0,
279
+ BaseCircle1,
280
+ BaseCircle2,
281
+ PressionAngle,
282
+ DisfunctioningTwoCircles
283
+ }
284
+
285
+ // helper functions
286
+ function gw2center(
287
+ gw1: GearWheelProfile,
288
+ gw2: GearWheelProfile,
289
+ angleCenterCenter: number,
290
+ addInterAxis: number
291
+ ): number[] {
292
+ gw1.checkInitStep(1, 'helper.gw2center-1');
293
+ gw2.checkInitStep(1, 'helper.gw2center-2');
294
+ const interAxis = gw1.pr + gw2.pr + addInterAxis;
295
+ const c2x = gw1.cx + interAxis * Math.cos(angleCenterCenter);
296
+ const c2y = gw1.cy + interAxis * Math.sin(angleCenterCenter);
297
+ return [c2x, c2y, interAxis];
298
+ }
299
+ function baseCircles(
300
+ gw1: GearWheelProfile,
301
+ gw2: GearWheelProfile,
302
+ ibrr1: number,
303
+ iblr1: number,
304
+ ibrr2: number,
305
+ iblr2: number,
306
+ involSym: number,
307
+ involROpt: number,
308
+ involLOpt: number
309
+ ): number[] {
310
+ gw1.checkInitStep(3, 'helper.baseCircles-1');
311
+ gw2.checkInitStep(3, 'helper.baseCircles-2');
312
+ let brr1 = ibrr1;
313
+ let brr2 = ibrr2;
314
+ let blr1 = iblr1;
315
+ let blr2 = iblr2;
316
+ const involROpt2: EInvolOpt = involROpt as EInvolOpt;
317
+ const involLOpt2: EInvolOpt = involLOpt as EInvolOpt;
318
+ if (involROpt2 === EInvolOpt.Optimum) {
319
+ if (gw2.TN > gw1.TN) {
320
+ brr1 = gw1.dr;
321
+ brr2 = (brr1 * gw2.TN) / gw1.TN;
322
+ } else {
323
+ brr2 = gw2.dr;
324
+ brr1 = (brr2 * gw1.TN) / gw2.TN;
325
+ }
326
+ }
327
+ if (involLOpt2 === EInvolOpt.Optimum) {
328
+ if (gw2.TN > gw1.TN) {
329
+ blr1 = gw1.dr;
330
+ blr2 = (blr1 * gw2.TN) / gw1.TN;
331
+ } else {
332
+ blr2 = gw2.dr;
333
+ blr1 = (blr2 * gw1.TN) / gw2.TN;
334
+ }
335
+ }
336
+ if (involSym === 1) {
337
+ blr1 = brr1;
338
+ blr2 = brr2;
339
+ }
340
+ return [brr1, blr1, brr2, blr2];
341
+ }
342
+
343
+ class ActionLine {
344
+ gw1: GearWheelProfile;
345
+ gw2: GearWheelProfile;
346
+ initAngle1: number;
347
+ angleCenterCenter: number;
348
+ interAxis: number;
349
+ rightLeftCenter2: number;
350
+ msg: string;
351
+ apr: number; // angle pressure right
352
+ apl: number; // angle pressure left
353
+ lBDr = 0;
354
+ lBDl = 0;
355
+ laStartRr1 = 0;
356
+ laStartRr2 = 0;
357
+ laStartRl1 = 0;
358
+ laStartRl2 = 0;
359
+ aFODr1 = 0;
360
+ aFODr2 = 0;
361
+ aFODl1 = 0;
362
+ aFODl2 = 0;
363
+ lasr1 = 0;
364
+ lasr2 = 0;
365
+ lasl1 = 0;
366
+ lasl2 = 0;
367
+ firstToothUr1 = 0;
368
+ firstToothUl1 = 0;
369
+ ftdr1 = 0;
370
+ ftdl1 = 0;
371
+ constructor(
372
+ gw1: GearWheelProfile,
373
+ gw2: GearWheelProfile,
374
+ initAngle1: number,
375
+ angleCenterCenter: number,
376
+ interAxis: number,
377
+ rightLeftCenter2: number
378
+ ) {
379
+ // initialized members
380
+ this.gw1 = gw1;
381
+ this.gw2 = gw2;
382
+ this.initAngle1 = initAngle1;
383
+ this.angleCenterCenter = angleCenterCenter;
384
+ this.interAxis = interAxis;
385
+ this.rightLeftCenter2 = rightLeftCenter2;
386
+ // computed members
387
+ this.msg = '';
388
+ this.apr = 0;
389
+ this.apl = 0;
390
+ }
391
+ check1() {
392
+ this.gw1.checkInitStep(4, 'ActionLine.check1-1');
393
+ this.gw2.checkInitStep(4, 'ActionLine.check1-2');
394
+ if (this.interAxis > this.gw1.ar + this.gw2.ar) {
395
+ this.msg += `warn333: initAngle2 interAxis ${ffix(
396
+ this.interAxis
397
+ )} is too large compare to gw1.ar ${ffix(this.gw1.ar)} and gw2.ar ${ffix(
398
+ this.gw2.ar
399
+ )}\n`;
400
+ }
401
+ if (roundZero(this.gw1.brr * this.gw2.TN - this.gw2.brr * this.gw1.TN) !== 0) {
402
+ this.msg += `warn407: right ratios differ N1/N2 = ${this.gw1.TN} / ${
403
+ this.gw2.TN
404
+ } = ${ffix(this.gw1.TN / this.gw2.TN)} and brr1/brr2 = ${ffix(this.gw1.brr)}/${ffix(
405
+ this.gw2.brr
406
+ )} = ${ffix(this.gw1.brr / this.gw2.brr)}\n`;
407
+ }
408
+ if (roundZero(this.gw1.blr * this.gw2.TN - this.gw2.blr * this.gw1.TN) !== 0) {
409
+ this.msg += `warn408: left ratios differ N1/N2 = ${this.gw1.TN} / ${
410
+ this.gw2.TN
411
+ } = ${ffix(this.gw1.TN / this.gw2.TN)} and blr1/blr2 = ${ffix(this.gw1.blr)}/${ffix(
412
+ this.gw2.blr
413
+ )} = ${ffix(this.gw1.blr / this.gw2.blr)}\n`;
414
+ }
415
+ }
416
+ check2() {
417
+ this.gw1.checkInitStep(5, 'ActionLine.check2-1');
418
+ this.gw2.checkInitStep(5, 'ActionLine.check2-2');
419
+ if (roundZero(this.gw1.adt + this.gw2.adt - 1) > 0) {
420
+ this.msg += `warn281: addendum thickness too large: adt1 ${ffix(
421
+ this.gw1.adt
422
+ )} adt2 ${ffix(this.gw2.adt)}\n`;
423
+ }
424
+ const a1 = this.gw1.ar - this.gw1.pr;
425
+ const d1 = this.gw1.pr - this.gw1.dr;
426
+ const a2 = this.gw2.ar - this.gw2.pr;
427
+ const d2 = this.gw2.pr - this.gw2.dr;
428
+ if (roundZero(d2 - a1) < 0) {
429
+ this.msg += `warn282: addendum-1 ${ffix(a1)} larger than dedendum-2 ${ffix(d2)}\n`;
430
+ }
431
+ if (roundZero(d1 - a2) < 0) {
432
+ this.msg += `warn283: addendum-2 ${ffix(a2)} larger than dedendum-1 ${ffix(d1)}\n`;
433
+ }
434
+ }
435
+ calcActionLine() {
436
+ this.gw1.checkInitStep(4, 'ActionLine.calcActionLine-1');
437
+ this.gw2.checkInitStep(4, 'ActionLine.calcActionLine-2');
438
+ this.gw1.calcInvoluteAngles();
439
+ this.gw2.calcInvoluteAngles();
440
+ const dOFr1 = (this.interAxis * this.gw1.brr) / (this.gw1.brr + this.gw2.brr);
441
+ const dOFl1 = (this.interAxis * this.gw1.blr) / (this.gw1.blr + this.gw2.blr);
442
+ const dOFr2 = this.interAxis - dOFr1;
443
+ const dOFl2 = this.interAxis - dOFl1;
444
+ //const apr = Math.acos(gw1.brr / dOFr);
445
+ //const apl = Math.acos(gw1.blr / dOFl);
446
+ this.apr = Math.acos((this.gw1.brr + this.gw2.brr) / this.interAxis);
447
+ this.apl = Math.acos((this.gw1.blr + this.gw2.blr) / this.interAxis);
448
+ this.msg += `Pressure angular: right: ${ffix(radToDeg(this.apr))} left: ${ffix(
449
+ radToDeg(this.apl)
450
+ )} degree\n`;
451
+ this.lBDr = this.interAxis * Math.sin(this.apr);
452
+ this.lBDl = this.interAxis * Math.sin(this.apl);
453
+ this.msg += `Line of Action Maximum length: right: ${ffix(this.lBDr)} left: ${ffix(
454
+ this.lBDl
455
+ )} mm\n`;
456
+ // effective line of action right
457
+ const aOFDr1 = Math.PI / 2 + this.apr;
458
+ const aFDOr1 = aBFromLaLbAa(this.gw1.ar, dOFr1, aOFDr1);
459
+ this.aFODr1 = Math.PI - aOFDr1 - aFDOr1;
460
+ //const aBODr1 = this.gw1.involuteR.uFromL(this.gw1.ar); // this.gw1.rua
461
+ const aFODr1Alt = this.gw1.rua - this.apr - this.gw1.rwa;
462
+ //this.aFODr1 = aFODr1Alt;
463
+ if (roundZero(this.aFODr1 - aFODr1Alt) !== 0) {
464
+ throw `dbg378: aFODr1 ${this.aFODr1} and aFODr1Alt ${aFODr1Alt} differ`;
465
+ }
466
+ const lDFr1 = lcFromLaLbAc(dOFr1, this.gw1.ar, this.aFODr1);
467
+ const aOFDr2 = aOFDr1;
468
+ const aFDOr2 = aBFromLaLbAa(this.gw2.ar, dOFr2, aOFDr2);
469
+ this.aFODr2 = Math.PI - aOFDr2 - aFDOr2;
470
+ const aFODr2Alt = this.gw2.rua - this.apr - this.gw2.rwa;
471
+ //this.aFODr2 = aFODr2Alt;
472
+ if (roundZero(this.aFODr2 - aFODr2Alt) !== 0) {
473
+ throw `dbg379: aFODr2 ${this.aFODr2} and aFODr2Alt ${aFODr2Alt} differ`;
474
+ }
475
+ const lDFr2 = lcFromLaLbAc(dOFr2, this.gw2.ar, this.aFODr2);
476
+ const lalr = lDFr1 + lDFr2;
477
+ const laUr1 = lalr / this.gw1.brr;
478
+ const laUr2 = lalr / this.gw2.brr;
479
+ const laStartUr1 = this.gw1.rua - laUr1;
480
+ const laStartUr2 = this.gw2.rua - laUr2;
481
+ this.laStartRr1 = this.gw1.involuteR.lFromU(laStartUr1);
482
+ this.laStartRr2 = this.gw2.involuteR.lFromU(laStartUr2);
483
+ // effective line of action left
484
+ const aOFDl1 = Math.PI / 2 + this.apl;
485
+ const aFDOl1 = aBFromLaLbAa(this.gw1.ar, dOFl1, aOFDl1);
486
+ this.aFODl1 = Math.PI - aOFDl1 - aFDOl1;
487
+ const aFODl1Alt = this.gw1.lua - this.apl + this.gw1.lwa;
488
+ //this.aFODl1 = aFODl1Alt;
489
+ if (roundZero(this.aFODl1 - aFODl1Alt) !== 0) {
490
+ throw `dbg388: aFODl1 ${this.aFODl1} and aFODl1Alt ${aFODl1Alt} differ`;
491
+ }
492
+ const lDFl1 = lcFromLaLbAc(dOFl1, this.gw1.ar, this.aFODl1);
493
+ const aOFDl2 = aOFDr1;
494
+ const aFDOl2 = aBFromLaLbAa(this.gw2.ar, dOFl2, aOFDl2);
495
+ this.aFODl2 = Math.PI - aOFDl2 - aFDOl2;
496
+ const aFODl2Alt = this.gw2.lua - this.apl + this.gw2.lwa;
497
+ //this.aFODl2 = aFODl2Alt;
498
+ if (roundZero(this.aFODl2 - aFODl2Alt) !== 0) {
499
+ throw `dbg389: aFODl2 ${this.aFODl2} and aFODl2Alt ${aFODl2Alt} differ`;
500
+ }
501
+ const lDFl2 = lcFromLaLbAc(dOFl2, this.gw2.ar, this.aFODl2);
502
+ const lall = lDFl1 + lDFl2;
503
+ const laUl1 = lall / this.gw1.blr;
504
+ const laUl2 = lall / this.gw2.blr;
505
+ const laStartUl1 = this.gw1.lua - laUl1;
506
+ const laStartUl2 = this.gw2.lua - laUl2;
507
+ this.laStartRl1 = this.gw1.involuteL.lFromU(laStartUl1);
508
+ this.laStartRl2 = this.gw2.involuteL.lFromU(laStartUl2);
509
+ this.msg += `Line of Action Effective length: right: ${ffix(lalr)} left: ${ffix(
510
+ lall
511
+ )} mm\n`;
512
+ this.msg += `Line of Action Effective rotation angle: right-1: ${ffix(
513
+ radToDeg(laUr1)
514
+ )} right-2: ${ffix(radToDeg(laUr2))} left-1: ${ffix(radToDeg(laUl1))} left-2: ${ffix(
515
+ radToDeg(laUl2)
516
+ )} degree\n`;
517
+ this.msg += `Line of Action Effective height: right-1: ${ffix(
518
+ this.gw1.ar - this.laStartRr1
519
+ )} right-2: ${ffix(this.gw2.ar - this.laStartRr2)} left-1: ${ffix(
520
+ this.gw1.ar - this.laStartRl1
521
+ )} left-2: ${ffix(this.gw2.ar - this.laStartRl2)} mm\n`;
522
+ this.lasr1 = ((2 * Math.PI) / this.gw1.TN) * this.gw1.brr;
523
+ this.lasr2 = ((2 * Math.PI) / this.gw2.TN) * this.gw2.brr;
524
+ this.msg += `Line of Action right: step length: 1: ${ffix(this.lasr1)} 2: ${ffix(
525
+ this.lasr2
526
+ )} mm\n`;
527
+ this.msg += `Line of Action right: nb of contact point: 1: ${ffix(
528
+ lalr / this.lasr1
529
+ )} 2: ${ffix(lalr / this.lasr2)}\n`;
530
+ this.lasl1 = ((2 * Math.PI) / this.gw1.TN) * this.gw1.blr;
531
+ this.lasl2 = ((2 * Math.PI) / this.gw2.TN) * this.gw2.blr;
532
+ this.msg += `Line of Action left: step length: 1: ${ffix(this.lasl1)} 2: ${ffix(
533
+ this.lasl2
534
+ )} mm\n`;
535
+ this.msg += `Line of Action left: nb of contact point: 1: ${ffix(
536
+ lall / this.lasl1
537
+ )} 2: ${ffix(lall / this.lasl2)}\n`;
538
+ }
539
+ calcContactPoint1() {
540
+ this.gw1.checkInitStep(5, 'ActionLine.calcContactPoint1');
541
+ this.firstToothUr1 = withinZero2Pi(
542
+ this.apr - (this.initAngle1 - this.angleCenterCenter) + this.gw1.rwp
543
+ );
544
+ //this.msg += `dbg625: apr ${ffix(this.apr)} initAngle1 ${ffix(this.initAngle1)} rwp ${ffix(this.gw1.rwp)} rad\n`;
545
+ //this.msg += `dbg626: firstToothUr1 ${ffix(this.firstToothUr1)} as ${ffix(this.gw1.as)} rad\n`;
546
+ while (roundZero(this.firstToothUr1 - this.gw1.as) >= 0) {
547
+ this.firstToothUr1 = roundZero(this.firstToothUr1 - this.gw1.as);
548
+ }
549
+ //this.msg += `dbg627: firstToothUr1 ${ffix(this.firstToothUr1)} rad\n`;
550
+ this.firstToothUl1 = withinZero2Pi(
551
+ this.apl +
552
+ (this.initAngle1 - this.angleCenterCenter) +
553
+ this.gw1.as * this.gw1.adt -
554
+ this.gw1.lwp
555
+ );
556
+ while (roundZero(this.firstToothUl1 - this.gw1.as) >= 0) {
557
+ this.firstToothUl1 = roundZero(this.firstToothUl1 - this.gw1.as);
558
+ }
559
+ this.ftdr1 = this.gw1.brr * this.firstToothUr1;
560
+ this.ftdl1 = this.gw1.blr * this.firstToothUl1;
561
+ //this.msg += `dbg112: right: ${ffix(this.ftdr1)} left: ${ffix(this.ftdl1)} mm\n`;
562
+ }
563
+ prepare() {
564
+ this.check1();
565
+ this.check2();
566
+ this.calcActionLine();
567
+ this.calcContactPoint1();
568
+ }
569
+ oneContactSpeed(
570
+ rnl: boolean,
571
+ lBD: number,
572
+ las: number,
573
+ ftd: number,
574
+ baser: number,
575
+ invo: Involute,
576
+ acc: number,
577
+ ap: number,
578
+ label: string,
579
+ color: string
580
+ ): tContour {
581
+ const speed = 0.4;
582
+ const larStepNb = Math.floor(lBD / (2 * las));
583
+ const ptu = (ftd + larStepNb * las) / baser;
584
+ const sign = rnl ? 1 : -1;
585
+ const [px, py, vx, vy] = invo.laptc(acc, sign * ap, ptu, speed);
586
+ this.msg += `speed ${label}: vx ${ffix(vx)} vy: ${ffix(vy)} m/s\n`;
587
+ const pt0 = point(px, py);
588
+ const aa = acc + sign * ap;
589
+ const rCtr = contour(px, py, color);
590
+ const pt1 = pt0.translatePolar(aa, -vy);
591
+ rCtr.addSegStrokeA(pt1.cx, pt1.cy);
592
+ const pt2 = pt1.translatePolar(aa - (sign * Math.PI) / 2, vx);
593
+ rCtr.addSegStrokeA(pt2.cx, pt2.cy);
594
+ rCtr.closeSegStroke();
595
+ return rCtr;
596
+ }
597
+ getContactSpeed(): tContour[] {
598
+ const ctrR1 = this.oneContactSpeed(
599
+ true,
600
+ this.lBDr,
601
+ this.lasr1,
602
+ this.ftdr1,
603
+ this.gw1.brr,
604
+ this.gw1.involuteR,
605
+ this.angleCenterCenter,
606
+ this.apr,
607
+ 'R1',
608
+ 'Black'
609
+ );
610
+ const ctrL1 = this.oneContactSpeed(
611
+ false,
612
+ this.lBDl,
613
+ this.lasl1,
614
+ this.ftdl1,
615
+ this.gw1.blr,
616
+ this.gw1.involuteL,
617
+ this.angleCenterCenter,
618
+ this.apl,
619
+ 'L1',
620
+ 'Black'
621
+ );
622
+ const rACtr: tContour[] = [];
623
+ rACtr.push(ctrR1);
624
+ rACtr.push(ctrL1);
625
+ return rACtr;
626
+ }
627
+ getContours(): tContour[] {
628
+ const rACtr: tContour[] = [];
629
+ rACtr.push(contourCircle(this.gw1.cx, this.gw1.cy, this.laStartRr1, 'SkyBlue'));
630
+ rACtr.push(contourCircle(this.gw1.cx, this.gw1.cy, this.laStartRl1, 'SlateBlue'));
631
+ rACtr.push(contourCircle(this.gw2.cx, this.gw2.cy, this.laStartRr2, 'SkyBlue'));
632
+ rACtr.push(contourCircle(this.gw2.cx, this.gw2.cy, this.laStartRl2, 'SlateBlue'));
633
+ const c1 = point(this.gw1.cx, this.gw1.cy);
634
+ const c2 = point(this.gw2.cx, this.gw2.cy);
635
+ const pr1 = c1.translatePolar(this.angleCenterCenter + this.apr, this.gw1.brr);
636
+ const pr4 = c2.translatePolar(this.angleCenterCenter + Math.PI + this.apr, this.gw2.brr);
637
+ const ctrLaFullR = contour(pr1.cx, pr1.cy, 'YellowGreen');
638
+ ctrLaFullR.addSegStrokeA(pr4.cx, pr4.cy);
639
+ ctrLaFullR.closeSegStroke();
640
+ rACtr.push(ctrLaFullR);
641
+ const pr2 = c1.translatePolar(this.angleCenterCenter - this.aFODr1, this.gw1.ar);
642
+ const pr3 = c2.translatePolar(this.angleCenterCenter + Math.PI - this.aFODr2, this.gw2.ar);
643
+ const ctrLaEffectiveR = contour(pr2.cx, pr2.cy, 'Yellow');
644
+ ctrLaEffectiveR.addSegStrokeA(pr3.cx, pr3.cy);
645
+ ctrLaEffectiveR.closeSegStroke();
646
+ rACtr.push(ctrLaEffectiveR);
647
+ const pl1 = c1.translatePolar(this.angleCenterCenter - this.apl, this.gw1.blr);
648
+ const pl4 = c2.translatePolar(this.angleCenterCenter + Math.PI - this.apl, this.gw2.blr);
649
+ const ctrLaFullL = contour(pl1.cx, pl1.cy, 'YellowGreen');
650
+ ctrLaFullL.addSegStrokeA(pl4.cx, pl4.cy);
651
+ ctrLaFullL.closeSegStroke();
652
+ rACtr.push(ctrLaFullL);
653
+ const pl2 = c1.translatePolar(this.angleCenterCenter + this.aFODl1, this.gw1.ar);
654
+ const pl3 = c2.translatePolar(this.angleCenterCenter + Math.PI + this.aFODl2, this.gw2.ar);
655
+ const ctrLaEffectiveL = contour(pl2.cx, pl2.cy, 'Yellow');
656
+ ctrLaEffectiveL.addSegStrokeA(pl3.cx, pl3.cy);
657
+ ctrLaEffectiveL.closeSegStroke();
658
+ rACtr.push(ctrLaEffectiveL);
659
+ rACtr.push(...this.getContactSpeed());
660
+ return rACtr;
661
+ }
662
+ getContactPoint(): Point[] {
663
+ const rApt: Point[] = [];
664
+ const c1 = point(this.gw1.cx, this.gw1.cy);
665
+ const cop1r0 = c1.translatePolar(this.angleCenterCenter + this.apr, this.gw1.brr);
666
+ const cop1l0 = c1.translatePolar(this.angleCenterCenter - this.apl, this.gw1.blr);
667
+ rApt.push(point(cop1r0.cx, cop1r0.cy, ShapePoint.eBigSquare));
668
+ rApt.push(point(cop1l0.cx, cop1l0.cy, ShapePoint.eBigSquare));
669
+ const cop1ra = this.angleCenterCenter + this.apr - Math.PI / 2;
670
+ const cop1la = this.angleCenterCenter - this.apl + Math.PI / 2;
671
+ const cop1r1 = cop1r0.translatePolar(cop1ra, this.ftdr1);
672
+ const cop1l1 = cop1l0.translatePolar(cop1la, this.ftdl1);
673
+ rApt.push(point(cop1r1.cx, cop1r1.cy, ShapePoint.eBigSquare));
674
+ rApt.push(point(cop1l1.cx, cop1l1.cy, ShapePoint.eBigSquare));
675
+ let cop1rdn = this.ftdr1;
676
+ while (cop1rdn + this.lasr1 < this.lBDr) {
677
+ cop1rdn += this.lasr1;
678
+ const cop1rn = cop1r0.translatePolar(cop1ra, cop1rdn);
679
+ rApt.push(point(cop1rn.cx, cop1rn.cy, ShapePoint.eBigSquare));
680
+ }
681
+ let cop1ldn = this.ftdl1;
682
+ while (cop1ldn + this.lasl1 < this.lBDl) {
683
+ cop1ldn += this.lasl1;
684
+ const cop1ln = cop1l0.translatePolar(cop1la, cop1ldn);
685
+ rApt.push(point(cop1ln.cx, cop1ln.cy, ShapePoint.eBigSquare));
686
+ }
687
+ return rApt;
688
+ }
689
+ getMsg(): string {
690
+ return this.msg;
691
+ }
692
+ getInitAngle2(): number {
693
+ let ftdr2 = this.lBDr - this.ftdr1;
694
+ while (roundZero(ftdr2 - this.lasr2) >= 0) {
695
+ ftdr2 = roundZero(ftdr2 - this.lasr2);
696
+ }
697
+ let ftdl2 = this.lBDl - this.ftdl1;
698
+ while (roundZero(ftdl2 - this.lasl2) >= 0) {
699
+ ftdl2 = roundZero(ftdl2 - this.lasl2);
700
+ }
701
+ const ftur2 = ftdr2 / this.gw2.brr;
702
+ const ftul2 = ftdl2 / this.gw2.blr;
703
+ const ftar2 = this.angleCenterCenter + Math.PI + this.apr - ftur2 + this.gw2.rwp;
704
+ const ftal2 = this.angleCenterCenter + Math.PI - this.apl + ftul2 + this.gw2.lwp;
705
+ const ftal2b = ftal2 - this.gw2.as * this.gw2.adt;
706
+ let angleL2 = 2 * Math.PI + withinZero2Pi(ftal2b);
707
+ while (roundZero(angleL2 - this.gw2.as - ftar2) >= 0) {
708
+ angleL2 = roundZero(angleL2 - this.gw2.as);
709
+ }
710
+ const angleDiff2 = angleL2 - ftar2;
711
+ const angleDiff1 = (angleDiff2 * this.gw2.brr) / this.gw1.brr;
712
+ const laDiffr2 = angleDiff2 * this.gw2.brr;
713
+ const laDiffl2 = angleDiff2 * this.gw2.blr;
714
+ this.msg += `slack angle: 1: ${ffix(radToDeg(angleDiff1))} 2: ${ffix(
715
+ radToDeg(angleDiff2)
716
+ )} degree\n`;
717
+ this.msg += `slack on action line: right-2: ${ffix(laDiffr2)} left-2: ${ffix(
718
+ laDiffl2
719
+ )} mm\n`;
720
+ let rInitAngle2 = 0;
721
+ if (this.rightLeftCenter2 === 0) {
722
+ rInitAngle2 = ftar2;
723
+ } else if (this.rightLeftCenter2 === 1) {
724
+ rInitAngle2 = ftal2b;
725
+ } else if (this.rightLeftCenter2 === 2) {
726
+ rInitAngle2 = ftar2 + angleDiff2 / 2;
727
+ } else {
728
+ throw `err221: initAngle2 rightLeftCenter2 ${this.rightLeftCenter2} has an unkown value`;
729
+ }
730
+ return withinPiPi(rInitAngle2);
731
+ }
732
+ }
733
+
734
+ function actionLine(
735
+ gw1: GearWheelProfile,
736
+ gw2: GearWheelProfile,
737
+ initAngle1: number,
738
+ angleCenterCenter: number,
739
+ interAxis: number,
740
+ rightLeftCenter2: number
741
+ ): ActionLine {
742
+ const rAL = new ActionLine(
743
+ gw1,
744
+ gw2,
745
+ initAngle1,
746
+ angleCenterCenter,
747
+ interAxis,
748
+ rightLeftCenter2
749
+ );
750
+ return rAL;
751
+ }
752
+
753
+ export { gwProfile, gw2center, baseCircles, actionLine };