Add maximum scallop angle to complement fret angles

This commit is contained in:
Luke Hubmayer-Werner 2025-02-06 21:05:53 +10:30
parent fbc86297a0
commit 158d15120a
3 changed files with 39 additions and 17 deletions

View File

@ -140,6 +140,7 @@ module TaperNeck(
num_frets = 24,
fret_widths = [],
fret_angle = 60, // 90 is semicircle
max_scallop_angle = 60, // match this to fret_angle for a nice continuous look
filler = false,
include_colours = [0, 1, 2, 3], // 0: Base neck/fretboard 1: Frets 2: Inlays 3: Side markers
){
@ -149,6 +150,7 @@ module TaperNeck(
neck_width_bridge = (num_strings-1)*string_spacing_bridge + string_margin*2;
function neck_width(fret) = lerp(neck_width_bridge, neck_width_nut, 2^(-fret/12));
function neck_width_mm(mm) = lerp(neck_width_bridge, neck_width_nut, mm/fret_scale_length(0));
function get_fret_width(fret) = fret_widths[clamp(0, fret, num_frets)];
max_fret_width = max(fret_widths);
max_fret_height = sin(fret_angle) * max_fret_width/2;
@ -181,11 +183,20 @@ module TaperNeck(
}
}
module scallop(fret) {
x0 = fret_scale_length(fret-1) - fret_widths[max(0, fret-1)]/2;
x1 = fret_scale_length(fret) + fret_widths[min(num_frets, fret)]/2;
x0 = fret_scale_length(fret-1) - get_fret_width(fret-1)/2;
x1 = fret_scale_length(fret) + get_fret_width(fret)/2;
xmid = lerp(x0, x1, 0.5);
// Radius it?
arc = arc_points([[x0, scallop_depth], [x1, scallop_depth], [xmid, 0]]);
xdelta = x0-x1;
maxdepth_angle = 90+arc_points_angle([[x0, scallop_depth], [x1, scallop_depth], [xmid, 0]]);
// echo(str(maxdepth_angle));
a = min(max_scallop_angle, maxdepth_angle);
fn = 50;
fn2 = fn * 2;
ca = cos(a);
sa = sin(a);
r = xdelta / (2*sa);
arc = [ for (i = [-fn:fn]) [xmid+xdelta*i/fn2, scallop_depth-r*(sqrt(1 - ((sa*i/fn)^2))-ca)] ];
// echo(arc);
rotate([90, 0, 90]) linear_extrude(neck_width_bridge, center=true) polygon(arc);
}
@ -201,23 +212,23 @@ module TaperNeck(
ca = cos(a);
sa = sin(a);
r = fw / (2*sa);
arc = [ for (i = [-fn:fn]) [fw*i/fn2, r*(sqrt(1 - pow(sa*(i/fn), 2))-ca)] ];
arc = [ for (i = [-fn:fn]) [fw*i/fn2, r*(sqrt(1 - ((sa*i/fn)^2))-ca)] ];
// echo("fret_bump", a, ca, arc);
rotate([90, 0, 90]) linear_extrude(neck_width_bridge, center=true) polygon(arc);
}
module fret_bumps() {
for (fret = [0:num_frets])
translate([0, fret_scale_length(fret), scallop_depth])
fret_bump(fret_widths[fret]);
fret_bump(get_fret_width(fret));
}
module intersect_fret_layers() {
for (fret = [0:num_frets]) {
translate([-500, fret_scale_length(fret)-fret_widths[fret]/2, -500])
cube([1000, fret_widths[fret], 1000]);
translate([-500, fret_scale_length(fret)-get_fret_width(fret)/2, -500])
cube([1000, get_fret_width(fret), 1000]);
}
// Some precision error with fret 0 :/
translate([-500, fret_scale_length(0)-fret_widths[0]/2+0.0006, -500])
cube([1000, fret_widths[0], 1000]);
translate([-500, fret_scale_length(0)-get_fret_width(0)/2+0.0006, -500])
cube([1000, get_fret_width(0), 1000]);
}
module fret_inlays() {
for (num_text = fret_inlays) {
@ -228,7 +239,7 @@ module TaperNeck(
diff = x0 - x1;
translate([0, lerp(x0, x1, 0.5), -0.5])
linear_extrude(30)
text(text = num_text[1], font = JP_Sans_Font, halign = "center", valign = "center", size = clamp(2, diff-fret_widths[fret]*2-2, 10));
text(text = num_text[1], font = JP_Sans_Font, halign = "center", valign = "center", size = clamp(2, diff-get_fret_width(fret)*2-2, 10));
}
}
}

View File

@ -74,9 +74,9 @@ module LockingGuitarTuner(holes=0) {
// translate([-12, 8]) LockingGuitarTuner();
render() difference() {
t = 24;
cube([23, 48, t]);
translate([12, 10, t-14]) LockingGuitarTuner(holes=10);
translate([12, 34, t-14]) LockingGuitarTuner(holes=10);
}
// render() difference() {
// t = 24;
// cube([23, 48, t]);
// translate([12, 10, t-14]) LockingGuitarTuner(holes=10);
// translate([12, 34, t-14]) LockingGuitarTuner(holes=10);
// }

View File

@ -38,6 +38,17 @@ function arc_points(tri_points, fragments_per_mm=5) =
a_step = a_sweep/steps
)
[for (i = [0:steps]) r*[cos(a_start+i*a_step), sin(a_start+i*a_step)] + cc];
// Modified version of above for when we just want the initial angle
function arc_points_angle(tri_points, fragments_per_mm=5) =
let(
cc = tri_circumcenter(tri_points),
r = norm(tri_points[0] - cc),
steps = ceil((norm(tri_points[2] - tri_points[0]) + norm(tri_points[2] - tri_points[1]))*fragments_per_mm),
normalized0 = (tri_points[0] - cc)/r,
normalized1 = (tri_points[1] - cc)/r,
a_start = atan2(normalized0[1], normalized0[0])
)
a_start;
function list_has(list, value) = len(search(value, list)) > 0;