chanter.scad
1use <BOSL/math.scad>
2
3$fn = $preview ? 0 : 180; // Make circles circular in final renders.
4
5// stops is an array of [d, h]
6module rod(stops) {
7 beg = stops[0][1];
8 end = stops[len(stops)-1][1];
9 p = concat([[0, beg]], stops, [[0, end]]);
10
11 halfp = [for (i = p) [i[0]/2, i[1]]];
12 rotate_extrude(convexity=4) {
13 polygon(halfp);
14 }
15}
16
17// Drill a tonehole.
18// The center of the tonehole will intersect [0, od, h] before rotation.
19//
20// Instrument makers think about
21// drilling from the outside of the pipe in.
22// So we need to know the outside diameter of the pipe.
23//
24// For now, we're pretending the pipe has a consistent outside diameter.
25// BOSL2 may have something that will let us calculate od given h and measurements.
26module tonehole(od, h, d, undercut=0, rot=0) {
27 render(convexity=2)
28 rotate([0, 0, rot]) {
29 translate([0, -od/2, h]) {
30 // Intersect with a cube to ensure an undercut tonehole doesn't drill past the center of the instrument
31 intersection() {
32 rotate([-90+undercut, 0, 0]) {
33 cylinder(d=d, h=od, center=true);
34 }
35 cube(od, center=true);
36 }
37 }
38 }
39}
40
41function inch(x) = x * 25.4;
42
43od = inch(0.762);
44
45height = 360;
46
47module chanter() {
48 difference() {
49 union() {
50 cylinder(d=16, h=height);
51 cylinder(d1=od, d2=16, h=280); // A nice taper
52 }
53
54 tonehole(od, 56.0, inch(0.162));
55 tonehole(od, 89.0, inch(0.182));
56 tonehole(od, 122.2, inch(0.201));
57 tonehole(od, 153.2, inch(0.180));
58 tonehole(od, 190.1, inch(0.183));
59 tonehole(od, 222.6, inch(0.187));
60 tonehole(od, 252.2, inch(0.162));
61 tonehole(od, 275.5, inch(0.173), rot=180);
62
63 rod([
64 [7.1, height],
65 [inch(0.189), 337],
66 [inch(0.195), mean([330.7, 334.1])],
67 [inch(0.200), mean([325.5, 329.6])],
68 [inch(0.205), mean([318.2, 321.8])],
69 [inch(0.210), mean([315.2, 317.7])],
70 [inch(0.215), mean([309.7, 312.5])],
71 [inch(0.220), mean([302.0, 305.5])],
72 [inch(0.225), mean([294.7, 297.4])],
73 [inch(0.230), mean([288.5, 292.0])],
74 [inch(0.235), mean([282.5, 284.0])],
75 [inch(0.241), mean([274.0, 278.7])],
76 [inch(0.245), mean([269.0, 269.0])],
77 [inch(0.250), mean([265.0, 265.0])],
78 [inch(0.259), mean([266.0, 266.0])],
79 [inch(0.270), mean([237.9, 241.5])],
80 [inch(0.280), mean([224.5, 226.5])],
81 [inch(0.290), mean([209.0, 212.2])],
82 [inch(0.300), mean([195.4, 195.4])],
83 [inch(0.310), mean([183.0, 185.2])],
84 [inch(0.320), mean([179.0, 183.4])],
85 [inch(0.330), mean([160.2, 160.2])],
86 [inch(0.340), mean([135.0, 104.7])],
87 [inch(0.350), mean([119.6, 123.6])],
88 [inch(0.360), mean([104.0, 110.4])],
89 [inch(0.370), mean([ 79.0, 81.0, 89.2])],
90 [inch(0.380), mean([ 61.0, 63.0, 66.0])],
91 [inch(0.390), mean([ 59.5, 61.6])],
92 [inch(0.400), mean([ 51.0, 54.5, 56.5])],
93 [inch(0.410), mean([ 27.0, 29.5])],
94 [inch(0.420), mean([ 21.5, 29.0])],
95 [inch(0.427), mean([ 0.0, 0.0])],
96 ]);
97 }
98}
99
100module tenon(top=false, h=198, od=od-5, depth=20, thickness=2, clearance=0.12) {
101 module cut() {
102 cylinder(h=h+depth, d=od-thickness+clearance);
103 cylinder(h=h, d=50);
104 }
105
106 if (top) {
107 difference() {
108 children();
109 cut();
110 }
111 } else {
112 intersection() {
113 children();
114 cut();
115 }
116 }
117}
118
119chanter();