2024-04-01 14:55:15 +10:30
|
|
|
include <common.scad>
|
|
|
|
include <AluTCommon.scad>
|
|
|
|
|
|
|
|
semitone_strings = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "X", "XI"];
|
2024-04-02 16:06:13 +10:30
|
|
|
octave_strings = ["", ".", "..", "_"];
|
2024-04-01 14:55:15 +10:30
|
|
|
octave_scales = [1.1, 1, 0.9, 0.8];
|
|
|
|
|
2024-04-01 20:19:34 +10:30
|
|
|
z_resolution = $preview ? 0.5 : 0.1;
|
2024-04-02 13:38:10 +10:30
|
|
|
profile_arc_steps_backside = $preview ? 8 : 360;
|
|
|
|
profile_arc_steps_topside = $preview ? 8 : 60;
|
2024-04-01 14:55:15 +10:30
|
|
|
|
|
|
|
fret_width = 2.4; //2.8; // Jumbo = 0.11", 0.055" tall
|
2024-04-01 20:19:34 +10:30
|
|
|
zero_fret_width = fret_width*1.5;
|
|
|
|
zero_fret_extra_height = 1.2;
|
|
|
|
fret_angle = 60; //Fret angle of 45° is normal, anything over 60 will not work correctly
|
2024-04-01 14:55:15 +10:30
|
|
|
tube_radius = Cap_Spine + T_circumcenter[0];
|
2024-04-01 20:19:34 +10:30
|
|
|
standard_profile_center_x = T_circumcenter[0];
|
2024-04-01 23:31:40 +10:30
|
|
|
x_min = standard_profile_center_x - tube_radius;
|
2024-04-02 23:52:43 +10:30
|
|
|
// minimum_y_width = 26.4517;
|
|
|
|
// standard_y_width = 28;
|
|
|
|
|
|
|
|
|
|
|
|
module fret_tube(from_fret, to_fret, scale_offset = 0, nut_spacing = 10, bridge_spacing = 20, strings = 3, y_width_extra_mm = 8, fingerboard_min_thick = 2.5, fingerboard_max_thick = 5, place_on_z0 = false, string_mms = false) {
|
|
|
|
spacing_scale = bridge_spacing/nut_spacing;
|
|
|
|
y_width_extra = y_width_extra_mm / ((strings-1) * nut_spacing);
|
|
|
|
y_width_nut = ((strings-1) * nut_spacing) + y_width_extra_mm;
|
|
|
|
y_width_bridge = ((strings-1) * bridge_spacing) + y_width_extra_mm;
|
|
|
|
string_diameters = string_mms ? string_mms : [for (i=[1:strings]) 2];
|
|
|
|
|
2024-04-01 14:55:15 +10:30
|
|
|
function fsl(fret_number) = fret_scale_length(fret_number + scale_offset);
|
2024-04-01 23:31:40 +10:30
|
|
|
z0 = fsl(0);
|
2024-04-02 23:52:43 +10:30
|
|
|
z_min = fsl(to_fret) - fret_width/2;
|
|
|
|
z_max = fsl(from_fret) + zero_fret_width/2;
|
|
|
|
Cap_Length = z_max - z_min;
|
|
|
|
echo(str("Cap length from fret ", from_fret, " to ", to_fret, " is ", Cap_Length, "mm"));
|
|
|
|
|
|
|
|
function get_desired_top_width(z) = lerp(y_width_bridge, y_width_nut, z/z0);
|
|
|
|
function get_desired_profile_radius(top_width) =
|
2024-04-01 23:31:40 +10:30
|
|
|
let (
|
|
|
|
x = fingerboard_max_thick,
|
2024-04-02 23:52:43 +10:30
|
|
|
cc = tri_circumcenter([[x, -top_width/2], [x, top_width/2], [x_min, 0]])
|
2024-04-01 23:31:40 +10:30
|
|
|
)
|
|
|
|
cc[0]-x_min;
|
|
|
|
|
2024-04-01 14:55:15 +10:30
|
|
|
|
2024-04-01 20:19:34 +10:30
|
|
|
module solid_tube(cap_taper = 1.5) {
|
|
|
|
function get_x_max(z) =
|
|
|
|
let (
|
|
|
|
fret_num = mm_to_fret_number(z)-scale_offset,
|
|
|
|
nearest_fret = round(fret_num),
|
|
|
|
nearest_fret_height = fingerboard_max_thick + ((nearest_fret == 0) ? zero_fret_extra_height : 0),
|
|
|
|
nearest_fret_mm = fsl(nearest_fret)
|
|
|
|
)
|
|
|
|
z;
|
2024-04-02 23:52:43 +10:30
|
|
|
module outline_xy(top_width, x_max = fingerboard_max_thick, rounding_radius = 1.5, backside = true, topside = true) {
|
|
|
|
profile_radius = get_desired_profile_radius(top_width);
|
2024-04-01 23:31:40 +10:30
|
|
|
profile_radius_scale = profile_radius / tube_radius;
|
2024-04-01 20:19:34 +10:30
|
|
|
profile_center_x = (profile_radius_scale-1.0)*tube_radius + standard_profile_center_x;
|
2024-04-01 23:31:40 +10:30
|
|
|
|
|
|
|
// Backside should join up relatively straight across the whole mesh
|
|
|
|
a_backside_start = acos((-2-profile_center_x)/profile_radius);
|
|
|
|
a_backside_end = 360 - a_backside_start;
|
|
|
|
a_backside_step = (a_backside_end - a_backside_start)/profile_arc_steps_backside;
|
|
|
|
// Frontside should have very detailed topology
|
|
|
|
a_topside_start = acos((x_max-profile_center_x)/profile_radius);
|
|
|
|
a_topside_end = 360 - a_topside_start;
|
|
|
|
a_topside_step = (a_backside_start - a_topside_start)/profile_arc_steps_topside;
|
|
|
|
|
2024-04-01 20:19:34 +10:30
|
|
|
function pt(a) = [profile_center_x + profile_radius*cos(a), profile_radius*sin(a)];
|
2024-04-01 23:31:40 +10:30
|
|
|
backside_points = backside ? [for (i = [0:profile_arc_steps_backside]) pt(a_backside_start + i*a_backside_step)] : [];
|
|
|
|
topside_points_1 = topside ? [for (i = [0:profile_arc_steps_topside]) pt(a_topside_start + i*a_topside_step)] : [];
|
|
|
|
topside_points_2 = topside ? [for (i = [0:profile_arc_steps_topside]) pt(a_backside_end + i*a_topside_step)] : [];
|
|
|
|
polygon(points = concat(topside_points_1, backside_points, topside_points_2));
|
|
|
|
|
2024-04-02 23:52:43 +10:30
|
|
|
top_width_actual = pt(a_topside_start)[1] * 2;
|
|
|
|
echo(TopWidthTarget=top_width, PScale=profile_radius_scale, r=profile_radius, TopWidth=top_width_actual, StringSpacing=(top_width-y_width_extra_mm)/(strings-1));
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
module fret_bumps(w=100) {
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([fingerboard_max_thick - fret_width/2, w/2, fsl(from_fret)])
|
2024-04-01 20:19:34 +10:30
|
|
|
rotate([90,0,0]) cylinder(h = w, r = zero_fret_width/2, $fn=32);
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([fingerboard_max_thick - fret_width/2, w/2, 0])
|
2024-04-01 20:19:34 +10:30
|
|
|
for (fret = [from_fret+1:to_fret])
|
|
|
|
translate([0, 0, fsl(fret)])
|
|
|
|
rotate([90,0,0]) cylinder(h = w, r = fret_width/2, $fn=32);
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
|
|
|
|
module scallops(w=100) {
|
2024-04-02 23:52:43 +10:30
|
|
|
o = fret_width/2 * sin(fret_angle);
|
|
|
|
y0 = fingerboard_min_thick;
|
|
|
|
y1 = fingerboard_max_thick - (fret_width/2 * cos(fret_angle));
|
|
|
|
for (fret = [from_fret+1:to_fret])
|
2024-04-01 14:55:15 +10:30
|
|
|
let(
|
2024-04-02 23:52:43 +10:30
|
|
|
x0 = fsl(fret-1) - o,
|
|
|
|
x1 = fsl(fret) + o,
|
2024-04-02 16:06:13 +10:30
|
|
|
x_mid = (x0+x1)/2,
|
|
|
|
pts = [[x0, y1], [x1, y1], [x_mid, y0]],
|
2024-04-01 14:55:15 +10:30
|
|
|
cc = tri_circumcenter(pts),
|
2024-04-02 16:06:13 +10:30
|
|
|
r = norm([x0, y1] - cc),
|
2024-04-02 23:52:43 +10:30
|
|
|
// r2 = r^2,
|
2024-04-02 16:06:13 +10:30
|
|
|
a_start = acos((x0 - cc[0])/r),
|
|
|
|
a_end = acos((x1 - cc[0])/r),
|
|
|
|
a_sweep = a_end - a_start,
|
|
|
|
a_step = a_sweep/10
|
2024-04-01 14:55:15 +10:30
|
|
|
) {
|
2024-04-02 16:06:13 +10:30
|
|
|
// echo(a_start=a_start, x0=x0, cc=cc);
|
|
|
|
translate([cc[1], 0, cc[0]])
|
|
|
|
rotate([90,0,0])
|
|
|
|
// cylinder(h = w, r = r, center = true);
|
|
|
|
linear_extrude(height = w, center = true)
|
2024-04-02 23:52:43 +10:30
|
|
|
polygon([for (i = [0:10]) [-r*sin(a_start+i*a_step), r*cos(a_start+i*a_step)]]);
|
|
|
|
// polygon([for (x = [x1-x_mid:0.05:x0-x_mid]) [-sqrt(r2 - x^2), x]]);
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module basic_fretboard() {
|
|
|
|
intersection() {
|
|
|
|
hull() {
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([0,0,z_max]) linear_extrude(0.001) outline_xy(get_desired_top_width(z_max));
|
|
|
|
translate([0,0,z_min]) linear_extrude(0.001) outline_xy(get_desired_top_width(z_min));
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
union() {
|
|
|
|
color("black") fret_bumps();
|
2024-04-02 23:52:43 +10:30
|
|
|
color("white", alpha=0.01) translate([-50,-50,z_min]) cube([50 + fingerboard_max_thick - (fret_width/2 * cos(fret_angle)), 100, Cap_Length]);
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make a solid tube and then subtract the notches
|
|
|
|
difference() {
|
|
|
|
basic_fretboard();
|
2024-04-02 23:52:43 +10:30
|
|
|
color("red") scallops();
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
// color("red") scallops();
|
|
|
|
}
|
|
|
|
|
2024-04-02 16:06:13 +10:30
|
|
|
module fret_number_text(fret) {
|
|
|
|
octave = floor(fret/12);
|
|
|
|
semitone = fret%12;
|
|
|
|
octave_scale = octave_scales[octave];
|
|
|
|
text(semitone_strings[semitone], size=4*octave_scale, halign="center", valign="center", font="Noto Sans", $fa=1, $fs=0.1);
|
|
|
|
translate([0, 2.5])
|
|
|
|
text(octave_strings[octave], size=5*octave_scale, halign="center", valign="center", font="Noto Sans", $fa=1, $fs=0.1);
|
|
|
|
}
|
|
|
|
|
2024-04-01 23:31:40 +10:30
|
|
|
module fret_number_markers(engrave_depth=1) {
|
|
|
|
color("purple")
|
|
|
|
// for (fret = [from_fret:to_fret])
|
|
|
|
for (fret = [from_fret+1:to_fret]) {
|
|
|
|
zn = fsl(fret);
|
2024-04-02 23:52:43 +10:30
|
|
|
pr = get_desired_profile_radius(get_desired_top_width(zn));
|
2024-04-01 23:31:40 +10:30
|
|
|
p_x0 = pr+x_min;
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([p_x0, 0, zn]) rotate([90,25,-asin((p_x0+2)/pr)])
|
2024-04-02 16:06:13 +10:30
|
|
|
translate([0, 0, pr-engrave_depth]) linear_extrude(engrave_depth+1)
|
|
|
|
fret_number_text(fret);
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([p_x0, 0, zn]) rotate([90,-25,180+asin((p_x0+2)/pr)])
|
2024-04-02 16:06:13 +10:30
|
|
|
translate([0, 0, pr-engrave_depth]) linear_extrude(engrave_depth+1)
|
|
|
|
fret_number_text(fret);
|
2024-04-01 23:31:40 +10:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([0, 0, place_on_z0 ? -z_min : 0])
|
2024-04-01 14:55:15 +10:30
|
|
|
difference() {
|
|
|
|
solid_tube(1.5);
|
2024-04-02 23:52:43 +10:30
|
|
|
linear_extrude(z_max+1) T_hole();
|
2024-04-01 23:31:40 +10:30
|
|
|
fret_number_markers();
|
2024-04-02 23:52:43 +10:30
|
|
|
tapered_T_hole(z0 = z_min, z1 = z_min+3);
|
|
|
|
tapered_T_hole(z0 = z_max-3, z1 = z_max+0.0001, o0 = 0, o1 = 1);
|
2024-04-01 14:55:15 +10:30
|
|
|
// Version number
|
2024-04-02 23:52:43 +10:30
|
|
|
translate([-10,10,z_max-0.5]) linear_extrude(1) text("06", size=5, halign="center", valign="center", font="Noto Sans");
|
2024-04-01 14:55:15 +10:30
|
|
|
}
|
|
|
|
|
2024-04-02 23:52:43 +10:30
|
|
|
color("silver")
|
|
|
|
for (s = [0:strings-1]) {
|
|
|
|
t = s - (strings/2) + 0.5;
|
|
|
|
hull() {
|
|
|
|
translate([fingerboard_max_thick+7, t*bridge_spacing, 0]) cylinder(h = 0.01, d = string_diameters[s], $fn=24);
|
|
|
|
translate([fingerboard_max_thick+3, t*nut_spacing, fsl(0)]) cylinder(h = 0.01, d = string_diameters[s], $fn=24);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-04-01 14:55:15 +10:30
|
|
|
|
2024-04-02 23:52:43 +10:30
|
|
|
// Long Bass (34")
|
|
|
|
fret_tube(from_fret=0, to_fret=36, scale_offset=-5, nut_spacing=10, bridge_spacing=20, strings=3, string_mms=[2.54, 2.159, 1.651]);
|
|
|
|
// Strat scale (25.5")
|
|
|
|
translate([50, 0])
|
|
|
|
fret_tube(from_fret=0, to_fret=30, scale_offset=0, nut_spacing=7, bridge_spacing=11, strings=6, string_mms=[0.8938, 0.8128, 0.6096, 0.4064, 0.2794, 0.2286]);
|
|
|
|
// Smaller
|
|
|
|
translate([100, 0])
|
|
|
|
fret_tube(from_fret=0, to_fret=24, scale_offset=3, nut_spacing=7, bridge_spacing=11, strings=5, string_mms=[0.8938, 0.8128, 0.6096, 0.4064, 0.2794]);
|