Neale Pickett
·
2025-11-28
complete.scad
1include <../common.scad>
2use <MCAD/regular_shapes.scad>
3
4height = 360.0;
5od = 16.0;
6od_derlin = od + 0.5;
7id_bot = 13.2;
8id_top = 5.51;
9cut_height = 155; // Where to cut it in half
10axianov = false; // Axianov tone holes?
11
12rev = "preview";
13stamp = str(rev);
14
15module tonehole_axianov(h=10, d=10, undercut=0) {
16 r = d/2;
17 area = PI*r*r;
18
19 rounding_r = 2;
20 rounding_area = (1 - PI/4) * (rounding_r^2); // area lost to rounding
21 goal_area = area + rounding_area;
22
23 w = 6.25; // Marat uses 6.25mm on every hole, so we will too
24 l = goal_area / w;
25
26 rotate([0, 0, -90]) {
27 translate([od/2, 0, h]) {
28 rotate([0, -90+undercut, 0]) {
29 // Scoot it down a hair so it will penetrate the entire tube when rotated
30 translate([0, 0, -od/2]) {
31 render(convexity=2)
32 intersection() {
33 cube([l, w, 20]);
34 union() {
35 translate([r, r, 0]) cylinder(r=r, h=20, center=true);
36 translate([r, 0, 0]) cube(20, center=true);
37 translate([0, r, 0]) cube(20, center=true);
38 }
39 }
40 }
41 }
42 }
43 }
44}
45
46module tonehole(h=10, d=10, undercut=0) {
47 if (axianov) {
48 tonehole_axianov(h, d, undercut);
49 } else {
50 rotate([0, 0, -90]) {
51 translate([od/2, 0, h]) {
52 rotate([0, -90+undercut, 0]) {
53 translate([0, 0, -od/2]) {
54 cylinder(d=d, h=20);
55 }
56 }
57 }
58 }
59 }
60 // Cutaways. I don't like them, but if you do, uncomment this.
61 // translate([0, -od/2 - 8, h]) rotate([0, 90, 0]) cylinder(r=10, h=50, center=true);
62}
63
64
65// Something like David Daye's Penny Chanter,
66// based on my measurements and undercut hints on David's web site.
67// This is symmetrical, so both pieces can be printed at the same time,
68// with color changes
69module chanter() {
70 difference () {
71 union() {
72 // The core part of the instrument is this brass tube
73 difference() {
74 brass() cylinder(h=height, d=od);
75
76 // Seam guides
77 translate([0, od/2, 0]) cylinder(d=1, h=400);
78 }
79
80 // David adds this outer Derlin tube as an upgrade option
81 difference() {
82 derlin() translate([0, 0, 40.0]) cylinder(h=290, d=od_derlin);
83
84 // The slits up the sides serve three purposes:
85 // 1. directs the slicer to place seams in it (and not on the face)
86 // 2. provides alignment guides for attaching the two pieces
87 // 3. looks like an intentional stylistic thing
88 rotate([0, 0, 85]) translate([0, od_derlin/2, 0]) cylinder(d=1, h=cut_height+20); // overlap
89 rotate([0, 0, -85]) translate([0, od_derlin/2, cut_height-20]) cylinder(d=1, h=400);
90 }
91
92 // These little doodads are probably just to hide the Derlin seam
93 ivory() translate([0, 0, 30.0]) {
94 cylinder(h=3, d1=od, d2=22.0);
95 translate([0, 0, 3]) cylinder(h=9, d=22.0);
96 }
97 ivory() translate([0, 0, height - 30.0 - 12]) {
98 cylinder(h=12, d=22.0);
99 }
100 }
101
102 // Seam guides
103 translate([0, 11, 0]) cylinder(d=1, h=400);
104
105 // Inner bore, which runs up to the place where the reed drops in
106 translate([0, 0, 0]) cylinder(h=337.01, d1=id_bot, d2=id_top);
107 translate([0, 0, 337]) cylinder(h=23.1, d1=id_top, d2=7.1);
108
109 // I totally dig David's minimalist aesthetic
110 translate([0, 0, 3]) rings(d=16.0);
111
112 // Sigil
113 translate([0, 0, 4]) intersection() {
114 cylinder_tube(50, od/2+0.5, 1);
115 union() {
116 translate([0, 0, 8]) rotate([90, 0, -90]) {
117 linear_extrude(height=d1, convexity=4) {
118 translate([-4, -5]) import("ruby.svg");
119 }
120 }
121 translate([0, 0, 4]) rotate([90, 90, -160]) {
122 linear_extrude(height=od, convexity=10) {
123 text(stamp, size=2, halign="right", valign="center");
124 }
125 }
126 }
127 }
128
129 // Tone Holes!
130 // XXX: Undercut angle should be taken into account here
131 tonehole(h=57.1, d=6.68); // E-
132 tonehole(h=87.0, d=4.25); // E
133 tonehole(h=118.0, d=8.33); // F#
134 tonehole(h=149.0, d=5.51, undercut=-15); // G
135 tonehole(h=184.5, d=7.75, undercut=15); // A
136 tonehole(h=184.5, d=7.75, undercut=-15); // A (wide undercut)
137 tonehole(h=219.0, d=6.72, undercut=15); // B
138 tonehole(h=250.0, d=5.50, undercut=30); // C
139 rotate([0, 0, 180]) tonehole(h=270.0, d=7.11, undercut=30); // D
140 }
141}
142
143module tenon(top=false, h=cut_height, od=od, depth=20, thickness=2) {
144 module cut() {
145 cylinder(h=cut_height+depth, d=od-thickness-clearance);
146 cylinder(h=cut_height, d=50);
147 }
148
149 if (top) {
150 difference() {
151 children();
152 cut();
153 }
154 } else {
155 intersection() {
156 children();
157 cut();
158 }
159 }
160}
161
162chanter();
163//translate([0, 50, 360]) rotate([180, 0, 0]) chanter();
164