1use {
25 crate::prelude::*,
26 scad_tree_math::{dcos, dsin},
27 std::collections::HashMap,
28};
29
30fn lerp(start: Pt3, end: Pt3, n_steps: usize, step: usize) -> Pt3 {
31 start + ((end - start) / n_steps as f64 * step as f64)
32}
33
34fn m_table_lookup(m: i32) -> HashMap<&'static str, f64> {
44 let m_table = m_table();
45 let mut m = m;
46 if m < 2 {
47 m = 2;
48 }
49 loop {
50 if m_table.contains_key(&m) {
51 break;
52 }
53 m -= 1;
54 }
55 m_table[&m].clone()
56}
57
58fn thread_height_from_pitch(pitch: f64) -> f64 {
64 3.0f64.sqrt() / 2.0 * pitch
65}
66
67fn d_min_from_d_maj_pitch(d_maj: f64, pitch: f64) -> f64 {
75 d_maj - 2.0 * 5.0 / 8.0 * thread_height_from_pitch(pitch)
76}
77
78#[allow(clippy::too_many_arguments)]
100fn threaded_cylinder(
101 d_min: f64,
102 d_maj: f64,
103 pitch: f64,
104 length: f64,
105 segments: u64,
106 lead_in_degrees: f64,
107 lead_out_degrees: f64,
108 left_hand_thread: bool,
109 center: bool,
110) -> Scad {
111 let lead_in = lead_in_degrees > 0.0;
112 let lead_out = lead_out_degrees > 0.0;
113 let thread_length = length - 0.7 * pitch;
114 let n_revolutions = thread_length / pitch;
115 let n_steps = (n_revolutions * segments as f64) as usize;
116 let z_step = thread_length / n_steps as f64;
117 let step_angle = 360.0 / segments as f64;
118 let n_lead_in_steps = (segments as f64 * lead_in_degrees / 360.0 + 2.0) as usize;
119 let n_lead_out_steps = (segments as f64 * lead_out_degrees / 360.0) as usize;
120 let mut lead_in_step = 2;
121 let mut lead_out_step = n_lead_out_steps;
122
123 let thread_profile0 = Pt3::new(d_min / 2.0, 0.0, 3.0 / 4.0 * pitch);
124 let thread_profile1 = Pt3::new(d_maj / 2.0, 0.0, 7.0 / 16.0 * pitch);
125 let thread_profile2 = Pt3::new(d_min / 2.0, 0.0, 0.0);
126 let thread_profile3 = Pt3::new(d_maj / 2.0, 0.0, 5.0 / 16.0 * pitch);
127
128 let lerp_profile1 = Pt3::new(d_min / 2.0, 0.0, 7.0 / 16.0 * pitch);
129 let lerp_profile3 = Pt3::new(d_min / 2.0, 0.0, 5.0 / 16.0 * pitch);
130
131 let lead_in_start_profile0 = thread_profile0;
132 let lead_in_start_profile2 = thread_profile2;
133 let lead_in_start_profile1 = lerp(
134 lerp_profile1,
135 thread_profile1,
136 n_lead_in_steps,
137 lead_in_step,
138 );
139 let lead_in_start_profile3 = lerp(
140 lerp_profile3,
141 thread_profile3,
142 n_lead_in_steps,
143 lead_in_step,
144 );
145 lead_in_step += 1;
146
147 let lead_out_end_profile1 = lerp(lerp_profile1, thread_profile1, n_lead_out_steps, 1);
148 let lead_out_end_profile3 = lerp(lerp_profile3, thread_profile3, n_lead_out_steps, 1);
149
150 let mut vertices: Vec<Pt3> = Vec::new();
151 let mut indices: Vec<usize> = Vec::new();
152
153 vertices.push(lead_in_start_profile0);
155 vertices.push(lead_in_start_profile1);
156 vertices.push(lead_in_start_profile2);
157 vertices.push(lead_in_start_profile3);
158
159 if left_hand_thread {
160 indices.append(&mut vec![2, 1, 0]);
161 indices.append(&mut vec![3, 1, 2]);
162 } else {
163 indices.append(&mut vec![0, 1, 2]);
164 indices.append(&mut vec![2, 1, 3]);
165 }
166
167 let mut p4;
169 let mut p5;
170 let mut p6;
171 let mut p7;
172
173 let lead_in_profile0 = lead_in_start_profile0;
174 let mut lead_in_profile1 = lead_in_start_profile1;
175 let lead_in_profile2 = lead_in_start_profile2;
176 let mut lead_in_profile3 = lead_in_start_profile3;
177
178 let lead_out_profile0 = thread_profile0;
179 let mut lead_out_profile1 = thread_profile1;
180 let lead_out_profile2 = thread_profile2;
181 let mut lead_out_profile3 = thread_profile3;
182
183 for step in 0..(n_steps - 1) {
184 let mut angle = step_angle * (step + 1) as f64;
185 if left_hand_thread {
186 angle *= -1.0;
187 }
188 let c = dcos(angle);
189 let s = dsin(angle);
190 if lead_in_step < n_lead_in_steps && lead_in {
191 p4 = Pt3::new(
192 c * lead_in_profile0.x,
193 s * lead_in_profile0.x,
194 z_step * step as f64 + lead_in_profile0.z,
195 );
196 p5 = Pt3::new(
197 c * lead_in_profile1.x,
198 s * lead_in_profile1.x,
199 z_step * step as f64 + lead_in_profile1.z,
200 );
201 p6 = Pt3::new(
202 c * lead_in_profile2.x,
203 s * lead_in_profile2.x,
204 z_step * step as f64 + lead_in_profile2.z,
205 );
206 p7 = Pt3::new(
207 c * lead_in_profile3.x,
208 s * lead_in_profile3.x,
209 z_step * step as f64 + lead_in_profile3.z,
210 );
211
212 lead_in_step += 1;
213 lead_in_profile1 = lerp(
214 lead_in_start_profile1,
215 thread_profile1,
216 n_lead_in_steps,
217 lead_in_step,
218 );
219 lead_in_profile3 = lerp(
220 lead_in_start_profile3,
221 thread_profile3,
222 n_lead_in_steps,
223 lead_in_step,
224 );
225 } else if lead_out_step > 0 && step >= n_steps - n_lead_out_steps && lead_out {
226 p4 = Pt3::new(
227 c * lead_out_profile0.x,
228 s * lead_out_profile0.x,
229 z_step * step as f64 + lead_out_profile0.z,
230 );
231 p5 = Pt3::new(
232 c * lead_out_profile1.x,
233 s * lead_out_profile1.x,
234 z_step * step as f64 + lead_out_profile1.z,
235 );
236 p6 = Pt3::new(
237 c * lead_out_profile2.x,
238 s * lead_out_profile2.x,
239 z_step * step as f64 + lead_out_profile2.z,
240 );
241 p7 = Pt3::new(
242 c * lead_out_profile3.x,
243 s * lead_out_profile3.x,
244 z_step * step as f64 + lead_out_profile3.z,
245 );
246 lead_out_step -= 1;
247 lead_out_profile1 = lerp(
248 thread_profile1,
249 lead_out_end_profile1,
250 n_lead_out_steps,
251 n_lead_out_steps - lead_out_step,
252 );
253 lead_out_profile3 = lerp(
254 thread_profile3,
255 lead_out_end_profile3,
256 n_lead_out_steps,
257 n_lead_out_steps - lead_out_step,
258 );
259 } else {
260 p4 = Pt3::new(
261 c * thread_profile0.x,
262 s * thread_profile0.x,
263 z_step * step as f64 + thread_profile0.z,
264 );
265 p5 = Pt3::new(
266 c * thread_profile1.x,
267 s * thread_profile1.x,
268 z_step * step as f64 + thread_profile1.z,
269 );
270 p6 = Pt3::new(
271 c * thread_profile2.x,
272 s * thread_profile2.x,
273 z_step * step as f64 + thread_profile2.z,
274 );
275 p7 = Pt3::new(
276 c * thread_profile3.x,
277 s * thread_profile3.x,
278 z_step * step as f64 + thread_profile3.z,
279 );
280 }
281
282 vertices.push(p4);
283 vertices.push(p5);
284 vertices.push(p6);
285 vertices.push(p7);
286
287 let index_offset = step * 4;
288 if left_hand_thread {
289 indices.append(&mut vec![
290 3 + index_offset,
291 5 + index_offset,
292 1 + index_offset,
293 ]);
294 indices.append(&mut vec![
295 7 + index_offset,
296 5 + index_offset,
297 3 + index_offset,
298 ]);
299 indices.append(&mut vec![1 + index_offset, 4 + index_offset, index_offset]);
300 indices.append(&mut vec![
301 5 + index_offset,
302 4 + index_offset,
303 1 + index_offset,
304 ]);
305 indices.append(&mut vec![index_offset, 6 + index_offset, 2 + index_offset]);
306 indices.append(&mut vec![4 + index_offset, 6 + index_offset, index_offset]);
307 indices.append(&mut vec![
308 2 + index_offset,
309 7 + index_offset,
310 3 + index_offset,
311 ]);
312 indices.append(&mut vec![
313 6 + index_offset,
314 7 + index_offset,
315 2 + index_offset,
316 ]);
317 } else {
318 indices.append(&mut vec![
319 1 + index_offset,
320 5 + index_offset,
321 3 + index_offset,
322 ]);
323 indices.append(&mut vec![
324 3 + index_offset,
325 5 + index_offset,
326 7 + index_offset,
327 ]);
328 indices.append(&mut vec![index_offset, 4 + index_offset, 1 + index_offset]);
329 indices.append(&mut vec![
330 1 + index_offset,
331 4 + index_offset,
332 5 + index_offset,
333 ]);
334 indices.append(&mut vec![2 + index_offset, 6 + index_offset, index_offset]);
335 indices.append(&mut vec![index_offset, 6 + index_offset, 4 + index_offset]);
336 indices.append(&mut vec![
337 3 + index_offset,
338 7 + index_offset,
339 2 + index_offset,
340 ]);
341 indices.append(&mut vec![
342 2 + index_offset,
343 7 + index_offset,
344 6 + index_offset,
345 ]);
346 }
347 } let index_offset = (n_steps - 2) * 4;
350 if left_hand_thread {
351 indices.append(&mut vec![
352 5 + index_offset,
353 7 + index_offset,
354 6 + index_offset,
355 ]);
356 indices.append(&mut vec![
357 4 + index_offset,
358 5 + index_offset,
359 6 + index_offset,
360 ]);
361 } else {
362 indices.append(&mut vec![
363 6 + index_offset,
364 7 + index_offset,
365 5 + index_offset,
366 ]);
367 indices.append(&mut vec![
368 6 + index_offset,
369 5 + index_offset,
370 4 + index_offset,
371 ]);
372 }
373
374 let mut faces = Faces::with_capacity(indices.len() / 3);
375 for i in (0..indices.len()).step_by(3) {
376 faces.push(Indices::from_indices(vec![
377 indices[i] as u64,
378 indices[i + 1] as u64,
379 indices[i + 2] as u64,
380 ]));
381 }
382 let convexity = (length / pitch) as u64 + 1;
383 let threads = polyhedron!(Pt3s::from_pt3s(vertices), faces, convexity);
384
385 let rod = Polyhedron::cylinder(d_min / 2.0 + 0.0001, length, segments).into_scad();
386
387 let mut result = threads + rod;
388
389 if center {
390 result = translate!([0.0, 0.0, -length / 2.0], result;);
391 }
392 result
393}
394
395pub fn threaded_rod(
413 m: i32,
414 length: f64,
415 segments: u64,
416 lead_in_degrees: f64,
417 lead_out_degrees: f64,
418 left_hand_thread: bool,
419 center: bool,
420) -> Scad {
421 let thread_info = m_table_lookup(m);
422 let pitch = thread_info["pitch"];
423 let d_maj = thread_info["external_dMaj"];
424 let d_min = d_min_from_d_maj_pitch(d_maj, pitch);
425
426 threaded_cylinder(
427 d_min,
428 d_maj,
429 pitch,
430 length,
431 segments,
432 lead_in_degrees,
433 lead_out_degrees,
434 left_hand_thread,
435 center,
436 )
437}
438
439#[allow(clippy::too_many_arguments)]
459pub fn hex_bolt(
460 m: i32,
461 length: f64,
462 head_height: f64,
463 segments: u64,
464 lead_in_degrees: f64,
465 chamfered: bool,
466 left_hand_thread: bool,
467 center: bool,
468) -> Scad {
469 let thread_info = m_table_lookup(m);
470 let pitch = thread_info["pitch"];
471 let d_maj = thread_info["external_dMaj"];
472 let head_diameter = thread_info["nut_width"];
473 let d_min = d_min_from_d_maj_pitch(d_maj, pitch);
474
475 let mut rod = threaded_cylinder(
476 d_min,
477 d_maj,
478 pitch,
479 length,
480 segments,
481 0.0,
482 lead_in_degrees,
483 left_hand_thread,
484 false,
485 );
486 rod = translate!([0.0, 0.0, head_height], rod;);
487
488 let mut head = Polyhedron::linear_extrude(
489 &dim2::circumscribed_polygon(6, head_diameter / 2.0),
490 head_height,
491 )
492 .into_scad();
493 if chamfered {
494 let chamfer_size = thread_info["chamfer_size"];
495 head = head
496 - Scad::external_cylinder_chamfer(
497 chamfer_size,
498 1.0,
499 (0.25 * head_diameter * 0.25 * head_diameter
500 + 0.5 * head_diameter * 0.5 * head_diameter)
501 .sqrt(),
502 head_height,
503 segments,
504 center,
505 );
506 }
507 let mut bolt = rod + head;
508 if center {
509 bolt = translate!([0.0, 0.0, -((head_height + length) / 2.0)], bolt;);
510 }
511 bolt
512}
513
514pub fn tap(m: i32, length: f64, segments: u64, left_hand_thread: bool, center: bool) -> Scad {
528 let thread_info = m_table_lookup(m);
529 let pitch = thread_info["pitch"];
530 let d_maj = thread_info["internal_dMaj"];
531 let d_min = d_min_from_d_maj_pitch(d_maj, pitch);
532
533 threaded_cylinder(
534 d_min,
535 d_maj,
536 pitch,
537 length,
538 segments,
539 0.0,
540 0.0,
541 left_hand_thread,
542 center,
543 )
544}
545
546pub fn hex_nut(
562 m: i32,
563 height: f64,
564 segments: u64,
565 chamfered: bool,
566 left_hand_thread: bool,
567 center: bool,
568) -> Scad {
569 let thread_info = m_table_lookup(m);
570 let nut_width = thread_info["nut_width"];
571
572 let mut nut_tap = tap(m, height + 20.0, segments, left_hand_thread, center);
573 nut_tap = translate!([0.0, 0.0, -10.0], nut_tap;);
574
575 let nut_blank =
576 Polyhedron::linear_extrude(&dim2::circumscribed_polygon(6, nut_width / 2.0), height)
577 .into_scad();
578
579 let mut nut = nut_blank - nut_tap;
580 if chamfered {
581 let chamfer_size = thread_info["chamfer_size"];
582 nut = nut
583 - Scad::external_cylinder_chamfer(
584 chamfer_size,
585 1.0,
586 (0.25 * nut_width * 0.25 * nut_width + 0.5 * nut_width * 0.5 * nut_width).sqrt(),
587 height,
588 segments,
589 center,
590 );
591 }
592
593 if center {
594 nut = translate!([0.0, 0.0, -height / 2.0], nut;);
595 }
596
597 nut
598}
599
600fn m_table() -> HashMap<i32, HashMap<&'static str, f64>> {
602 HashMap::from([
603 (
604 2,
605 HashMap::from([
606 ("pitch", 0.4),
607 ("external_dMaj", 1.886),
608 ("internal_dMaj", 2.148),
609 ("nut_width", 4.0),
610 ("chamfer_size", 1.45),
611 ]),
612 ),
613 (
614 3,
615 HashMap::from([
616 ("pitch", 0.5),
617 ("external_dMaj", 2.874),
618 ("internal_dMaj", 3.172),
619 ("nut_width", 5.5),
620 ("chamfer_size", 1.6),
621 ]),
622 ),
623 (
624 4,
625 HashMap::from([
626 ("pitch", 0.7),
627 ("external_dMaj", 3.838),
628 ("internal_dMaj", 4.219),
629 ("nut_width", 7.0),
630 ("chamfer_size", 1.8),
631 ]),
632 ),
633 (
634 5,
635 HashMap::from([
636 ("pitch", 0.8),
637 ("external_dMaj", 4.826),
638 ("internal_dMaj", 5.24),
639 ("nut_width", 8.0),
640 ("chamfer_size", 1.9),
641 ]),
642 ),
643 (
644 6,
645 HashMap::from([
646 ("pitch", 1.0),
647 ("external_dMaj", 5.794),
648 ("internal_dMaj", 6.294),
649 ("nut_width", 10.0),
650 ("chamfer_size", 2.1),
651 ]),
652 ),
653 (
655 7,
656 HashMap::from([
657 ("pitch", 1.0),
658 ("external_dMaj", 6.794),
659 ("internal_dMaj", 7.294),
660 ("nut_width", 13.0),
661 ("chamfer_size", 2.45),
662 ]),
663 ),
664 (
665 8,
666 HashMap::from([
667 ("pitch", 1.25),
668 ("external_dMaj", 7.76),
669 ("internal_dMaj", 8.34),
670 ("nut_width", 13.0),
671 ("chamfer_size", 2.45),
672 ]),
673 ),
674 (
676 9,
677 HashMap::from([
678 ("pitch", 1.25),
679 ("external_dMaj", 8.76),
680 ("internal_dMaj", 9.34),
681 ("nut_width", 16.0),
682 ("chamfer_size", 2.8),
683 ]),
684 ),
685 (
686 10,
687 HashMap::from([
688 ("pitch", 1.5),
689 ("external_dMaj", 9.732),
690 ("internal_dMaj", 10.396),
691 ("nut_width", 16.0),
692 ("chamfer_size", 2.8),
693 ]),
694 ),
695 (
697 11,
698 HashMap::from([
699 ("pitch", 1.5),
700 ("external_dMaj", 10.73),
701 ("internal_dMaj", 11.387),
702 ("nut_width", 18.0),
703 ("chamfer_size", 3.0),
704 ]),
705 ),
706 (
707 12,
708 HashMap::from([
709 ("pitch", 1.75),
710 ("external_dMaj", 11.7),
711 ("internal_dMaj", 12.453),
712 ("nut_width", 18.0),
713 ("chamfer_size", 3.0),
714 ]),
715 ),
716 (
717 14,
718 HashMap::from([
719 ("pitch", 2.0),
720 ("external_dMaj", 13.68),
721 ("internal_dMaj", 14.501),
722 ("nut_width", 21.0),
723 ("chamfer_size", 3.35),
724 ]),
725 ),
726 (
728 15,
729 HashMap::from([
730 ("pitch", 1.5),
731 ("external_dMaj", 14.73),
732 ("internal_dMaj", 15.407),
733 ("nut_width", 24.0),
734 ("chamfer_size", 3.7),
735 ]),
736 ),
737 (
738 16,
739 HashMap::from([
740 ("pitch", 2.0),
741 ("external_dMaj", 15.68),
742 ("internal_dMaj", 16.501),
743 ("nut_width", 24.0),
744 ("chamfer_size", 3.7),
745 ]),
746 ),
747 (
749 17,
750 HashMap::from([
751 ("pitch", 1.5),
752 ("external_dMaj", 16.73),
753 ("internal_dMaj", 17.407),
754 ("nut_width", 27.0),
755 ("chamfer_size", 3.9),
756 ]),
757 ),
758 (
759 18,
760 HashMap::from([
761 ("pitch", 2.5),
762 ("external_dMaj", 17.62),
763 ("internal_dMaj", 18.585),
764 ("nut_width", 27.0),
765 ("chamfer_size", 3.9),
766 ]),
767 ),
768 (
769 20,
770 HashMap::from([
771 ("pitch", 2.5),
772 ("external_dMaj", 19.62),
773 ("internal_dMaj", 20.585),
774 ("nut_width", 30.0),
775 ("chamfer_size", 4.25),
776 ]),
777 ),
778 (
779 22,
780 HashMap::from([
781 ("pitch", 3.0),
782 ("external_dMaj", 21.58),
783 ("internal_dMaj", 22.677),
784 ("nut_width", 34.0),
785 ("chamfer_size", 4.75),
786 ]),
787 ),
788 (
789 24,
790 HashMap::from([
791 ("pitch", 3.0),
792 ("external_dMaj", 23.58),
793 ("internal_dMaj", 24.698),
794 ("nut_width", 36.0),
795 ("chamfer_size", 4.9),
796 ]),
797 ),
798 (
800 25,
801 HashMap::from([
802 ("pitch", 2.0),
803 ("external_dMaj", 24.68),
804 ("internal_dMaj", 25.513),
805 ("nut_width", 41.0),
806 ("chamfer_size", 5.5),
807 ]),
808 ),
809 (
811 26,
812 HashMap::from([
813 ("pitch", 1.5),
814 ("external_dMaj", 25.73),
815 ("internal_dMaj", 26.417),
816 ("nut_width", 41.0),
817 ("chamfer_size", 5.5),
818 ]),
819 ),
820 (
821 27,
822 HashMap::from([
823 ("pitch", 3.0),
824 ("external_dMaj", 26.58),
825 ("internal_dMaj", 27.698),
826 ("nut_width", 41.0),
827 ("chamfer_size", 5.5),
828 ]),
829 ),
830 (
832 28,
833 HashMap::from([
834 ("pitch", 2.0),
835 ("external_dMaj", 27.68),
836 ("internal_dMaj", 28.513),
837 ("nut_width", 46.0),
838 ("chamfer_size", 6.0),
839 ]),
840 ),
841 (
842 30,
843 HashMap::from([
844 ("pitch", 3.5),
845 ("external_dMaj", 29.52),
846 ("internal_dMaj", 30.785),
847 ("nut_width", 46.0),
848 ("chamfer_size", 6.0),
849 ]),
850 ),
851 (
853 32,
854 HashMap::from([
855 ("pitch", 2.0),
856 ("external_dMaj", 31.68),
857 ("internal_dMaj", 32.513),
858 ("nut_width", 49.0),
859 ("chamfer_size", 6.4),
860 ]),
861 ),
862 (
863 33,
864 HashMap::from([
865 ("pitch", 3.5),
866 ("external_dMaj", 32.54),
867 ("internal_dMaj", 33.785),
868 ("nut_width", 49.0),
869 ("chamfer_size", 6.4),
870 ]),
871 ),
872 (
874 35,
875 HashMap::from([
876 ("pitch", 1.5),
877 ("external_dMaj", 34.73),
878 ("internal_dMaj", 35.416),
879 ("nut_width", 55.0),
880 ("chamfer_size", 7.0),
881 ]),
882 ),
883 (
884 36,
885 HashMap::from([
886 ("pitch", 4.0),
887 ("external_dMaj", 35.47),
888 ("internal_dMaj", 36.877),
889 ("nut_width", 55.0),
890 ("chamfer_size", 7.0),
891 ]),
892 ),
893 (
895 38,
896 HashMap::from([
897 ("pitch", 1.5),
898 ("external_dMaj", 37.73),
899 ("internal_dMaj", 38.417),
900 ("nut_width", 60.0),
901 ("chamfer_size", 7.5),
902 ]),
903 ),
904 (
905 39,
906 HashMap::from([
907 ("pitch", 4.0),
908 ("external_dMaj", 38.47),
909 ("internal_dMaj", 39.877),
910 ("nut_width", 60.0),
911 ("chamfer_size", 7.5),
912 ]),
913 ),
914 (
916 40,
917 HashMap::from([
918 ("pitch", 3.0),
919 ("external_dMaj", 39.58),
920 ("internal_dMaj", 40.698),
921 ("nut_width", 65.0),
922 ("chamfer_size", 8.2),
923 ]),
924 ),
925 (
926 42,
927 HashMap::from([
928 ("pitch", 4.5),
929 ("external_dMaj", 41.44),
930 ("internal_dMaj", 42.965),
931 ("nut_width", 65.0),
932 ("chamfer_size", 8.2),
933 ]),
934 ),
935 (
936 45,
937 HashMap::from([
938 ("pitch", 4.5),
939 ("external_dMaj", 44.44),
940 ("internal_dMaj", 45.965),
941 ("nut_width", 70.0),
942 ("chamfer_size", 8.75),
943 ]),
944 ),
945 (
946 48,
947 HashMap::from([
948 ("pitch", 5.0),
949 ("external_dMaj", 47.4),
950 ("internal_dMaj", 49.057),
951 ("nut_width", 75.0),
952 ("chamfer_size", 9.25),
953 ]),
954 ),
955 (
957 50,
958 HashMap::from([
959 ("pitch", 4.0),
960 ("external_dMaj", 49.47),
961 ("internal_dMaj", 50.892),
962 ("nut_width", 80.0),
963 ("chamfer_size", 9.5),
964 ]),
965 ),
966 (
967 52,
968 HashMap::from([
969 ("pitch", 5.0),
970 ("external_dMaj", 51.4),
971 ("internal_dMaj", 53.037),
972 ("nut_width", 80.0),
973 ("chamfer_size", 9.5),
974 ]),
975 ),
976 (
978 55,
979 HashMap::from([
980 ("pitch", 4.0),
981 ("external_dMaj", 54.47),
982 ("internal_dMaj", 55.892),
983 ("nut_width", 85.0),
984 ("chamfer_size", 10.25),
985 ]),
986 ),
987 (
988 56,
989 HashMap::from([
990 ("pitch", 5.5),
991 ("external_dMaj", 55.37),
992 ("internal_dMaj", 57.149),
993 ("nut_width", 85.0),
994 ("chamfer_size", 10.25),
995 ]),
996 ),
997 (
999 58,
1000 HashMap::from([
1001 ("pitch", 4.0),
1002 ("external_dMaj", 57.47),
1003 ("internal_dMaj", 58.892),
1004 ("nut_width", 90.0),
1005 ("chamfer_size", 10.75),
1006 ]),
1007 ),
1008 (
1009 60,
1010 HashMap::from([
1011 ("pitch", 5.5),
1012 ("external_dMaj", 59.37),
1013 ("internal_dMaj", 61.149),
1014 ("nut_width", 90.0),
1015 ("chamfer_size", 10.75),
1016 ]),
1017 ),
1018 (
1020 62,
1021 HashMap::from([
1022 ("pitch", 4.0),
1023 ("external_dMaj", 61.47),
1024 ("internal_dMaj", 62.892),
1025 ("nut_width", 95.0),
1026 ("chamfer_size", 11.25),
1027 ]),
1028 ),
1029 (
1031 63,
1032 HashMap::from([
1033 ("pitch", 1.5),
1034 ("external_dMaj", 62.73),
1035 ("internal_dMaj", 63.429),
1036 ("nut_width", 95.0),
1037 ("chamfer_size", 11.25),
1038 ]),
1039 ),
1040 (
1041 64,
1042 HashMap::from([
1043 ("pitch", 6.0),
1044 ("external_dMaj", 63.32),
1045 ("internal_dMaj", 65.421),
1046 ("nut_width", 95.0),
1047 ("chamfer_size", 11.25),
1048 ]),
1049 ),
1050 (
1052 65,
1053 HashMap::from([
1054 ("pitch", 4.0),
1055 ("external_dMaj", 64.47),
1056 ("internal_dMaj", 65.892),
1057 ("nut_width", 100.0),
1058 ("chamfer_size", 11.75),
1059 ]),
1060 ),
1061 (
1063 68,
1064 HashMap::from([
1065 ("pitch", 6.0),
1066 ("external_dMaj", 67.32),
1067 ("internal_dMaj", 69.241),
1068 ("nut_width", 100.0),
1069 ("chamfer_size", 11.75),
1070 ]),
1071 ),
1072 (
1074 70,
1075 HashMap::from([
1076 ("pitch", 6.0),
1077 ("external_dMaj", 69.32),
1078 ("internal_dMaj", 71.241),
1079 ("nut_width", 100.0),
1080 ("chamfer_size", 11.75),
1081 ]),
1082 ),
1083 (
1085 72,
1086 HashMap::from([
1087 ("pitch", 6.0),
1088 ("external_dMaj", 71.32),
1089 ("internal_dMaj", 73.241),
1090 ("nut_width", 110.0),
1091 ("chamfer_size", 13.0),
1092 ]),
1093 ),
1094 (
1096 75,
1097 HashMap::from([
1098 ("pitch", 6.0),
1099 ("external_dMaj", 74.32),
1100 ("internal_dMaj", 76.241),
1101 ("nut_width", 110.0),
1102 ("chamfer_size", 13.0),
1103 ]),
1104 ),
1105 (
1107 76,
1108 HashMap::from([
1109 ("pitch", 6.0),
1110 ("external_dMaj", 75.32),
1111 ("internal_dMaj", 77.241),
1112 ("nut_width", 110.0),
1113 ("chamfer_size", 13.0),
1114 ]),
1115 ),
1116 (
1118 78,
1119 HashMap::from([
1120 ("pitch", 2.0),
1121 ("external_dMaj", 77.68),
1122 ("internal_dMaj", 78.525),
1123 ("nut_width", 120.0),
1124 ("chamfer_size", 14.25),
1125 ]),
1126 ),
1127 (
1129 80,
1130 HashMap::from([
1131 ("pitch", 6.0),
1132 ("external_dMaj", 79.32),
1133 ("internal_dMaj", 81.241),
1134 ("nut_width", 120.0),
1135 ("chamfer_size", 14.25),
1136 ]),
1137 ),
1138 (
1140 82,
1141 HashMap::from([
1142 ("pitch", 2.0),
1143 ("external_dMaj", 81.68),
1144 ("internal_dMaj", 82.525),
1145 ("nut_width", 120.0),
1146 ("chamfer_size", 14.25),
1147 ]),
1148 ),
1149 (
1151 85,
1152 HashMap::from([
1153 ("pitch", 6.0),
1154 ("external_dMaj", 84.32),
1155 ("internal_dMaj", 86.241),
1156 ("nut_width", 130.0),
1157 ("chamfer_size", 15.25),
1158 ]),
1159 ),
1160 (
1162 90,
1163 HashMap::from([
1164 ("pitch", 6.0),
1165 ("external_dMaj", 89.32),
1166 ("internal_dMaj", 91.241),
1167 ("nut_width", 130.0),
1168 ("chamfer_size", 15.25),
1169 ]),
1170 ),
1171 (
1173 95,
1174 HashMap::from([
1175 ("pitch", 6.0),
1176 ("external_dMaj", 94.32),
1177 ("internal_dMaj", 96.266),
1178 ("nut_width", 130.0),
1179 ("chamfer_size", 15.25),
1180 ]),
1181 ),
1182 (
1184 100,
1185 HashMap::from([
1186 ("pitch", 6.0),
1187 ("external_dMaj", 99.32),
1188 ("internal_dMaj", 101.27),
1189 ("nut_width", 140.0),
1190 ("chamfer_size", 16.5),
1191 ]),
1192 ),
1193 ])
1194}