- commit
- d943160
- parent
- 98059a2
- author
- Neale Pickett
- date
- 2025-05-03 18:09:22 -0600 MDT
Add low C and fix ruby head
4 files changed,
+72,
-81
M
Makefile
+10,
-2
1@@ -1,13 +1,21 @@
2-all: lowd lowe
3+all: lowc lowd lowe
4
5 clean:
6 rm -f *.3mf
7
8 %.3mf: whistle.scad whistle.json tonehole.scad ruby.svg
9- openscad -o $@ -p whistle.json -P $(VARIANT) -D Section=\"$*\" $<
10+ openscad -o $@ -p whistle.json -P $(VARIANT) -D Section=$(SECTION) $<
11+
12+lowc: lowc-bot.3mf lowc-mid.3mf lowc-top.3mf
13+lowc-%.3mf: VARIANT="low c"
14
15 lowd: lowd-bot.3mf lowd-mid.3mf lowd-top.3mf
16 lowd-%.3mf: VARIANT="low d - Dixon"
17
18 lowe: lowe-bot.3mf lowe-mid.3mf lowe-top.3mf
19 lowe-%.3mf: VARIANT="low e"
20+
21+
22+%-top.3mf: SECTION=0
23+%-mid.3mf: SECTION=1
24+%-bot.3mf: SECTION=2
M
ruby.svg
+8,
-8
1@@ -1,9 +1,9 @@
2 <?xml version="1.0" encoding="utf-8"?>
3-<svg
4- xmlns="http://www.w3.org/2000/svg"
5- viewBox="18.4343 -8.2244 462.6288 499.8541"
6- width="0.924cm"
7- height="1cm"
8- preserveAspectRatio="meet">
9- <path style="stroke: rgb(0, 0, 0); fill: rgb(107, 84, 84); transform-origin: 249.749px 241.703px;" d="M 187.594 147.071 C 222.949 153.12 270.972 155.731 309.277 143.299 C 317.317 140.69 320.56 118.06 320.56 118.06 C 320.56 118.06 327.678 106.64 330.738 100.657 C 333.381 95.489 333.159 88.246 337.777 84.73 C 353.635 72.659 370.372 52.125 370.372 52.125 C 370.372 52.125 426.27 2.035 440.95 1.462 C 455.63 0.889 461.076 -0.732 469.218 12.046 C 477.36 24.824 453.472 138.031 453.472 138.031 C 453.472 138.031 453.953 147.266 444.263 160.449 C 434.573 173.632 447.673 167.61 440.944 190.185 C 434.215 212.76 438.017 200.224 427.718 215.259 C 417.419 230.294 397.67 242.025 388.524 251.061 C 379.378 260.097 386.798 291.019 386.798 291.019 C 386.798 291.019 387.847 326.31 381.141 347.368 C 374.435 368.426 346.18 391.255 346.18 391.255 C 346.18 391.255 325.323 472.928 268.206 481.757 C 211.089 490.586 166.483 394.938 166.483 394.938 C 166.483 394.938 144.005 389.647 131.704 371.16 C 119.403 352.673 108.748 336.052 108.361 311.035 C 107.974 286.018 101.518 264.509 101.518 264.509 C 101.518 264.509 89.405 262.542 85.275 256.613 C 81.145 250.684 78.859 245.845 70.152 238.568 C 59.127 229.354 42.841 226.273 39.22 199.414 C 35.599 172.555 36.125 179.11 36.125 179.11 C 36.125 179.11 23.121 168.902 31.274 144.728 C 39.427 120.554 89.353 134.561 107.159 120.958 C 124.965 107.355 114.883 115.961 133.013 98.781 C 151.143 81.601 175.442 122.255 175.442 122.255 C 175.442 122.255 178.724 145.553 187.594 147.071 Z" id="object-1" transform="matrix(0.99907297, 0.043046, -0.043046, 0.99907297, -2.7e-7, -2.3e-7)"/>
10-</svg>
11+<svg xmlns="http://www.w3.org/2000/svg" height="1cm" width="0.924cm" viewBox="0 0 500 500" xmlns:bx="https://boxy-svg.com">
12+ <defs>
13+ <bx:export>
14+ <bx:file format="png" path="ruby.png"/>
15+ </bx:export>
16+ </defs>
17+ <path style="stroke: rgb(0, 0, 0); fill: rgb(107, 84, 84); transform-box: fill-box; transform-origin: 50% 50%;" d="M 187.594 147.071 C 222.949 153.12 270.972 155.731 309.277 143.299 C 317.317 140.69 324.255 101.717 337.777 84.73 C 365.301 50.153 418.636 3.565 440.95 1.462 C 463.264 -0.641 461.076 -0.732 469.218 12.046 C 477.36 24.824 453.472 138.031 453.472 138.031 C 453.472 138.031 453.953 147.266 444.263 160.449 C 434.573 173.632 447.673 167.61 440.944 190.185 C 434.215 212.76 438.017 200.224 427.718 215.259 C 417.419 230.294 397.67 242.025 388.524 251.061 C 379.378 260.097 386.798 291.019 386.798 291.019 C 386.798 291.019 387.847 326.31 381.141 347.368 C 374.435 368.426 346.18 391.255 346.18 391.255 C 346.18 391.255 325.323 472.928 268.206 481.757 C 211.089 490.586 166.483 394.938 166.483 394.938 C 166.483 394.938 144.005 389.647 131.704 371.16 C 119.403 352.673 108.748 336.052 108.361 311.035 C 107.974 286.018 101.518 264.509 101.518 264.509 C 101.518 264.509 89.405 262.542 85.275 256.613 C 81.145 250.684 78.859 245.845 70.152 238.568 C 59.127 229.354 42.841 226.273 39.22 199.414 C 35.599 172.555 36.125 179.11 36.125 179.11 C 36.125 179.11 23.121 168.902 31.274 144.728 C 39.427 120.554 89.353 134.561 107.159 120.958 C 124.965 107.355 114.883 115.961 133.013 98.781 C 151.143 81.601 175.442 122.255 175.442 122.255 C 175.442 122.255 178.724 145.553 187.594 147.071 Z" id="object-1" transform="matrix(0.999073, 0.043046, -0.043046, 0.999073, 0.014376, 0.000286)"/>
18+</svg>
+14,
-41
1@@ -1,10 +1,10 @@
2 {
3 "parameterSets": {
4 "low d - Dixon": {
5+ "Text": "d",
6 "Height": "469",
7 "InnerDiameter": "20.9",
8- "Cut1": "190",
9- "Cut2": "240",
10+ "Cuts": "[190, 240]",
11 "Hole1": "[90, 7.45]",
12 "Hole2": "[130, 11.0]",
13 "Hole3": "[161, 9.45]",
14@@ -13,10 +13,10 @@
15 "Hole6": "[293, 7.45]"
16 },
17 "low e": {
18+ "Text": "e",
19 "Height": "406",
20 "InnerDiameter": "20.9",
21- "Cut1": "160",
22- "Cut2": "300",
23+ "Cuts": "[160, 300]",
24 "Hole1": "[261.3, 8.0]",
25 "Hole2": "[226.3, 9.5]",
26 "Hole3": "[191.9, 9.0]",
27@@ -24,44 +24,17 @@
28 "Hole5": "[116.4, 12.0]",
29 "Hole6": "[81.5, 7.5]"
30 },
31- "low e - pretty good, high E a bit flat": {
32- "Height": "406",
33- "InnerDiameter": "20.9",
34- "Cut1": "165",
35- "Cut2": "300",
36- "Hole1": "[261.3, 8.0]",
37- "Hole2": "[226.3, 9.5]",
38- "Hole3": "[191.8, 9.0]",
39- "Hole4": "[151.5, 7.5]",
40- "Hole5": "[116.0, 12.0]",
41- "Hole6": "[83.7, 7.0]"
42- },
43- "low e - awesome, except for extreme B3 reach": {
44- "Height": "409.4",
45+ "low c": {
46+ "Text": "c",
47+ "Height": "545.2",
48 "InnerDiameter": "20.9",
49- "Cut1": "165",
50- "Cut2": "300",
51- "Hole1": "[261.2, 8.0]",
52- "Hole2": "[226.2, 9.5]",
53- "Hole3": "[191.0, 9.0]",
54- "Hole4": "[150.5, 7.5]",
55- "Hole5": "[118.1, 12.0]",
56- "Hole6": "[70.5, 11.5]"
57- },
58- "low FAIL": {
59- "Height": "430",
60- "OuterDiameter": "25",
61- "InnerDiameter": "20",
62- "ORingDiameter": "1.5",
63- "ORingProtrusion": "0.98",
64- "Cut1": "165",
65- "Cut2": "300",
66- "Hole1": "[90, 6.5]",
67- "Hole2": "[122, 11]",
68- "Hole3": "[150, 8.5]",
69- "Hole4": "[202, 7.5]",
70- "Hole5": "[231, 8.5]",
71- "Hole6": "[267, 8.5]"
72+ "Cuts": "[195, 380]",
73+ "Hole1": "[326.3, 8.0]",
74+ "Hole2": "[283.2, 9.5]",
75+ "Hole3": "[238.1, 9.0]",
76+ "Hole4": "[187.1, 7.5]",
77+ "Hole5": "[145.3, 12.0]",
78+ "Hole6": "[101.8, 7.0]"
79 }
80 },
81 "fileFormatVersion": "1"
+40,
-30
1@@ -2,7 +2,7 @@ include <common.scad>
2 include <tonehole.scad>
3
4 // Which section to render for printing
5-Section = "e"; // [e:Everything, top:Top, mid:Middle, bot:Bottom]
6+Section = -1; // [-1:Everything, 0:Bottom, 1:Middle, 2:Top]
7
8 // Height of the instrument
9 Height = 469;
10@@ -16,14 +16,15 @@ ORingDiameter = 1.50; // 0.01
11 // How far beyond the outer diameter the O ring should protrude
12 ORingProtrusion = 0.80; // 0.01
13
14-// Height of first cut for a sectioned print
15-Cut1 = 190;
16-// Height of second cut for a sectioned print
17-Cut2 = 340;
18+// Cuts to make for a sectioned print
19+Cuts = [190, 340];
20
21 // Use Axianov tone holes?
22 AxianovHoles = true;
23
24+// Text to display on the back
25+Text = "d";
26+
27 Hole1 = [90, 7.45];
28 Hole2 = [130, 11.0];
29 Hole3 = [161, 9.45];
30@@ -31,6 +32,13 @@ Hole4 = [221, 7.45];
31 Hole5 = [254, 9.50];
32 Hole6 = [293, 7.45];
33
34+/* [ Esoterics ] */
35+// Angle for tone holes. Anything other than 45 will create challenging overhangs!
36+AxianovHoleAngle = 45;
37+
38+/* [ Hidden ] */
39+sortedCuts = [min(Cuts[0], Cuts[1]), max(Cuts[0], Cuts[1])];
40+
41 module whistle() {
42 difference() {
43 tube(h=Height, id=InnerDiameter, od=OuterDiameter);
44@@ -41,7 +49,7 @@ module whistle() {
45 }
46
47 // Decoration
48- for (i = [0, Cut1, Cut2]) {
49+ for (i = [0, sortedCuts[0], sortedCuts[1]]) {
50 translate([0, 0, i + 2]) {
51 translate([0, 0, 0]) tube(h=1, id=OuterDiameter-0.5, od=OuterDiameter+0.5);
52 translate([0, 0, 4]) tube(h=1, id=OuterDiameter-0.5, od=OuterDiameter+0.5);
53@@ -51,9 +59,9 @@ module whistle() {
54 for (hole = [Hole1, Hole2, Hole3, Hole4, Hole5, Hole6]) {
55 if (AxianovHoles) {
56 z = hole[0];
57- top = (z>Cut1) || (z>Cut2);
58+ top = (z>sortedCuts[0]) || (z>sortedCuts[1]);
59 m = [0, top?0:1, 0];
60- r = [90, top?45:135, 0];
61+ r = [90, top?90-AxianovHoleAngle:90+AxianovHoleAngle, 0];
62 translate([0, 0, hole[0]]) rotate(r) mirror(m) tonehole(d=hole[1]);
63 } else {
64 translate([0, 0, hole[0]]) rotate([90, 0, 0]) cylinder(d=hole[1], h=50);
65@@ -61,42 +69,44 @@ module whistle() {
66 }
67
68 // Ridges to catch seams
69- rotate([0, 0, 110]) translate([0, OuterDiameter/2, 0]) cylinder(h=Cut1, d=1);
70- rotate([0, 0, -110]) translate([0, OuterDiameter/2, Cut1]) cylinder(h=Cut2-Cut1, d=1);
71- rotate([0, 0, 110]) translate([0, OuterDiameter/2, Cut2]) cylinder(h=Height, d=1);
72+ rotate([0, 0, 110]) translate([0, OuterDiameter/2, 0]) cylinder(h=sortedCuts[0], d=1);
73+ rotate([0, 0, -110]) translate([0, OuterDiameter/2, sortedCuts[0]]) cylinder(h=sortedCuts[1]-sortedCuts[0], d=1);
74+ rotate([0, 0, 110]) translate([0, OuterDiameter/2, sortedCuts[1]]) cylinder(h=Height, d=1);
75+
76+ // Inner channel, seems to cause problems with the tenon join being too thin
77 //rotate([0, 0, 140]) translate([0, InnerDiameter/2, 0]) cylinder(h=Height, d=1);
78
79- // Ruby :)
80+ // Ruby head, and text on the back
81 // This makes previews slow, so we only do it in final renders.
82 if (!$preview) {
83 intersection() {
84- rotate([90, 0, 0]) {
85- translate([0, 5, OuterDiameter/2]) {
86- linear_extrude(height=OuterDiameter, center=true) {
87- import("ruby.svg", center=true);
88+ tube(h=50, id=OuterDiameter-0.5, od=OuterDiameter+10);
89+ union() {
90+ rotate([90, 0, 0]) {
91+ linear_extrude(height=OuterDiameter) {
92+ translate([-5, 0, 0]) import("ruby.svg");
93+ }
94+ }
95+ translate([0, 0, 8]) {
96+ rotate([90, 0, 180]) {
97+ linear_extrude(height=OuterDiameter) {
98+ text(Text, halign="center");
99+ }
100 }
101 }
102 }
103- tube(h=50, id=OuterDiameter-0.5, od=OuterDiameter+1);
104 }
105 }
106 }
107 }
108
109-if (Section == "top") {
110- tenon(h=Cut2, od=OuterDiameter, top=true) {
111- whistle();
112- }
113-} else if (Section == "mid") {
114- tenon(h=Cut1, od=OuterDiameter, top=true) {
115- tenon(h=Cut2, od=OuterDiameter, top=false) {
116+sectionedCuts = concat([-1000], sortedCuts, [1000]);
117+if (Section == -1) {
118+ whistle();
119+} else {
120+ tenon(h=sectionedCuts[Section], od=OuterDiameter, top=true) {
121+ tenon(h=sectionedCuts[Section+1], od=OuterDiameter, top=false) {
122 whistle();
123 }
124 }
125-} else if (Section == "bot") {
126- tenon(h=Cut1, od=OuterDiameter, top=false) {
127- whistle();
128- }
129-} else {
130- whistle();
131 }