Neale Pickett
·
2025-11-25
chanter.scad
1use <BOSL/math.scad>
2use <sigil.scad>
3
4rev = "preview";
5stamp = str(rev);
6
7$fn = $preview ? 0 : 180; // Make circles circular in final renders.
8
9// stops is an array of [d, h]
10module rod(stops) {
11 beg = stops[0][1];
12 end = stops[len(stops)-1][1];
13 p = concat([[0, beg]], stops, [[0, end]]);
14
15 halfp = [for (i = p) [i[0]/2, i[1]]];
16 rotate_extrude(convexity=4) {
17 polygon(halfp);
18 }
19}
20
21// Drill a tonehole.
22// The center of the tonehole will intersect [0, od, h] before rotation.
23//
24// Instrument makers think about
25// drilling from the outside of the pipe in.
26// So we need to know the outside diameter of the pipe.
27//
28// For now, we're pretending the pipe has a consistent outside diameter.
29// BOSL2 may have something that will let us calculate od given h and measurements.
30module tonehole(od, h, d, undercut=0, rot=0) {
31 render(convexity=2)
32 rotate([0, 0, rot]) {
33 translate([0, -od/2, h]) {
34 // Intersect with a cube to ensure an undercut tonehole doesn't drill past the center of the instrument
35 intersection() {
36 rotate([-90+undercut, 0, 0]) {
37 cylinder(d=d, h=od, center=true);
38 }
39 cube(od, center=true);
40 }
41 }
42 }
43}
44
45function inch(x) = x * 25.4;
46
47od = inch(0.762);
48
49height = 306;
50
51module chanter() {
52 difference() {
53 union() {
54 cylinder(d=16, h=height);
55 cylinder(d1=od, d2=16, h=280); // A nice taper
56 }
57
58 // Inner bore
59 cylinder(d1=10.8, d2=4.2, h=height-23);
60 translate([0, 0, height-23]) cylinder(d1=4.2, d2=7.1, h=23); // Reed insert
61
62 // Seam guides
63 translate([od/2, 0, 0]) rotate([0, -0.33, 0]) cylinder(d=1, h=400);
64
65 sigil(od, stamp);
66
67 tonehole(od, 56.0, inch(0.162));
68 tonehole(od, 89.0, inch(0.182));
69 tonehole(od, 122.2, inch(0.201));
70 tonehole(od, 153.2, inch(0.180));
71 tonehole(od, 190.1, inch(0.183));
72 tonehole(od, 222.6, inch(0.187));
73 tonehole(od, 252.2, inch(0.162));
74 tonehole(od, 275.5, inch(0.173), rot=180);
75
76 }
77}
78
79joint = 160; // Where to split it in half for printing
80module tenon(top=false, h=joint, od=od-5, depth=20, thickness=2, clearance=0.12) {
81 module cut() {
82 cylinder(h=h+depth, d=od-thickness+clearance);
83 cylinder(h=h, d=50);
84 }
85
86 if (top) {
87 difference() {
88 children();
89 cut();
90 }
91 } else {
92 intersection() {
93 children();
94 cut();
95 }
96 }
97}
98
99chanter();