PETG Classical guitar neck 1alpha

This commit is contained in:
Luke Hubmayer-Werner 2025-01-03 18:20:30 +10:30
parent 358f03761d
commit 9735e48126
3 changed files with 166 additions and 25 deletions

View File

@ -343,35 +343,61 @@ module bridge(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_t
module Nylon6String() {
fsl_mm = fret_scale_length(0);
echo(str("Making a Nylon 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in"))
assert(fsl_mm == Classical_Short_Scale_mm); // Make sure the function correctly uses our changed global
string_diameters_thous = [28, 32, 40, 30, 36, 42];
string_diameters_mm = string_diameters_thous * 0.0254;
num_frets = 20;
num_strings = 6;
// 56mm wide neck
string_spacing = 10; // 50mm E to e
string_margin = 3; // +6
neck_width = string_spacing*(num_strings-1) + string_margin*2;
scallop_depth = 2.5;
target_neck_thickness = 22;
fret_width=2.4;
echo(str("Making a Nylon 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in and neck width ", neck_width, "mm"));
assert(fsl_mm == Classical_Short_Scale_mm); // Make sure the function correctly uses our changed global
function CF_Span_Coords(full_length = 700, ply = 3) = [for (i=[0:ply-1]) [0, lerp(0, full_length-CF_Tube_Len, i/(ply-1)), CF_Square_Width*i]];
module CF_Span(full_length = 700, ply = 3, hole = true) {
for (v = CF_Span_Coords(full_length, ply))
translate(v) CFSquare(hole=hole);
}
reinforcing_tube_positions = flatten([
[
for (i=[-1,1]) each [
// Headside reinforcement
[i*21, -40+280, -4],
[i*17, -40+280, -12],
// Bridgeside reinforcement
[i*16, -40, -7],
]
],
[
// Bridgeside reinforcement
[0, -40, -4],
[0, -40, -15],
]]);
echo(reinforcing_tube_positions);
// Through span construction
span_coords = CF_Span_Coords();
reinforcing_square_positions = [
for (i=[-1,1]) each [ for (v = span_coords) [i*10, -40, -16] + v ]
];
echo(reinforcing_square_positions);
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing);
module CF_Span(full_length = 700, ply = 3, hole = true) {
for (i=[0:ply-1])
translate([0, lerp(0, full_length-CF_Tube_Len, i/(ply-1)), CF_Square_Width*i]) CFSquare(hole=hole);
}
// for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, -40, -16]) CF_Span();
// CFTube();
// %neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
module NeckFragment(from_fret, to_fret, to_origin=true, include_from_fret=false) {
module NeckFragment(from_fret, to_fret, to_origin=true, include_from_fret=false, test_tolerances_piece=false) {
x0 = fret_scale_length(to_fret) - fret_width/2;
x1 = fret_scale_length(from_fret) + ((include_from_fret)?1:(-1)) * fret_width/2;
xn = fsl_mm + fret_width;
translate([0,to_origin ? -x0 : 0,0]) render() difference() {
neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
translate([-100, 0, -100]) cube([200, x0, 200]);
translate([-100, x1, -100]) cube([200, xn-x1, 200]);
module TestTolerancesPiece() {
for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, 0, -16+(CF_Square_Width*2)]) CFSquareCutout(x0, x1, taper_length=2);
translate([ 12,0,-14]) CFSquareCutout(x0, x1, taper_length=2);
translate([ 12-CF_Square_Width,0,-14]) CFSquareCutout(x0, x1-8, taper_length=2, taper_x2=false);
@ -379,22 +405,57 @@ module Nylon6String() {
translate([-12+CF_Square_Width,0,-14]) CFSquareCutout(x0+8, x1, taper_length=2, taper_x1=false);
translate([20,0,-6]) CFTubeCutout(x0, x1, taper_length=2);
}
}
difference(){
NeckFragment(2, 3);
translate([-20,0,-1]) rotate([-90,180,180]) linear_extrude(3, center=true) text("PETG", size=3.5, halign="center", valign="center");
translate([-20,0,-6]) rotate([-90,180,180]) linear_extrude(3, center=true) text("1α", size=3.5, halign="center", valign="center");
translate([0,to_origin ? -x0 : 0,0]) render() difference() {
neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
translate([-100, 0, -100]) cube([200, x0, 200]);
translate([-100, x1, -100]) cube([200, xn-x1, 200]);
for (v = reinforcing_tube_positions) CFTubeCutout2(v, x0, x1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, x0, x1);
if (test_tolerances_piece) TestTolerancesPiece();
}
}
// translate([0,0,30]) difference() {
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
// for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, -40, -16]) CF_Span(hole=false);
// }
// Test tolerances piece
module TestTolerancesPiece() {
difference(){
NeckFragment(2, 3, test_tolerances_piece=true);
translate([-20,0,-1]) rotate([-90,180,180]) linear_extrude(3, center=true) text("PETG", size=3.5, halign="center", valign="center");
translate([-20,0,-6]) rotate([-90,180,180]) linear_extrude(3, center=true) text("1α", size=3.5, halign="center", valign="center");
}
}
// TestTolerancesPiece();
// for (m=[0,11]) mirror([m, 0, 0]) translate([29,10,-32]) rotate([0,-90,0]) NylonTuner();
module RealPiece(from_fret, to_fret, include_from_fret=false) {
midpoint = (fret_scale_length(from_fret) - fret_scale_length(to_fret) + (include_from_fret ? fret_width : 0))/2;
render() difference(){
NeckFragment(from_fret, to_fret, include_from_fret=include_from_fret);
color("red") for (ra = [[0,0,0], [0,0,180]]) rotate_around(ra, [0,midpoint,0])
translate([0,0,-9]) rotate([-90,180,180]) linear_extrude(3, center=true) text("PETG1α", size=2.5, halign="center", valign="center");
}
}
RealPiece(0, 8, include_from_fret=true);
%translate([100, 0, 0]) RealPiece(8, 21);
%translate([-100,0,0]) union() {
c_cf = [0.4, 0.5, 0.5];
%neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
// CF square stacks
for (v = reinforcing_tube_positions) color(c_cf) translate(v) CFTube();
for (v = reinforcing_square_positions) color(c_cf) translate(v) CFSquare();
// Approximate tuner placement
for (m=[0,1]) mirror([m, 0, 0]) translate([29,10,-32]) rotate([0,-90,0]) NylonTuner();
// Render strings above for spacing reference
string_excess = 80;
for (i = [0:num_strings-1]) {
translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin,0,5]) rotate([-90,0,0]) translate([0,0,-string_excess/2]) cylinder(h=fsl_mm+string_excess, d=string_diameters_mm[i], $fn=cyl_ld_fn);
}
}
// Debug markers to aid part slicing eyeballing
for (i = [150:250:1000]) {
%translate([50,i,0]) union() {text(str(i, "mm")); cube([50, 1, 1], center=true);}
// %for (i = [150:250:1000]) {
%for (i = [0:250:1000]) {
translate([50,i,0]) union() {text(str(i, "mm")); cube([50, 1, 1], center=true);}
}
}

View File

@ -73,3 +73,73 @@ module CFSquareCutout(x1, x2, tolerance = CF_Square_Width_tolerance, taper_x1 =
}
}
}
module CFTubeCutout2(v, block_y0, block_y1, tolerance = CF_Tube_OD_tolerance, VLH = false, taper_length = 2, taper_mul = 1.1) {
// Alternate approach: supply start vector v, and the bounding y values of the piece, taper on entry points only.
tolerance = tolerance + (VLH ? 0.3 : 0);
tube_y0 = v[1];
tube_y1 = tube_y0 + CF_Tube_Len;
OD = CF_Tube_OD + tolerance;
taper_OD = (CF_Tube_OD*taper_mul) + tolerance;
fn = 360;
// Full cylinder, unconditional
translate(v)
rotate([-90,0,0]) cylinder(h=CF_Tube_Len, d=OD, $fn=fn);
// Check for tapered holes
if ((block_y0 >= tube_y0) && (block_y0 < tube_y1)) // Tube protrudes through start of block
hull() {
translate([v[0], block_y0, v[2]])
rotate([-90,0,0]) cylinder(h=hull_epsilon, d=taper_OD, $fn=fn);
translate([v[0], block_y0+taper_length, v[2]])
rotate([-90,0,0]) cylinder(h=hull_epsilon, d=OD, $fn=fn);
}
if ((block_y1 <= tube_y1) && (block_y1 > tube_y0)) // Tube protrudes through end of block
hull() {
translate([v[0], block_y1-hull_epsilon, v[2]])
rotate([-90,0,0]) cylinder(h=hull_epsilon, d=taper_OD, $fn=fn);
translate([v[0], block_y1-hull_epsilon-taper_length, v[2]])
rotate([-90,0,0]) cylinder(h=hull_epsilon, d=OD, $fn=fn);
}
}
module CFSquareCutout2(v, block_y0, block_y1, tolerance = CF_Square_Width_tolerance, taper_length = 2, taper_mul = 1.1) {
w = CF_Square_Width + tolerance;
taper_w = (CF_Square_Width * taper_mul) + tolerance;
tube_y0 = v[1];
tube_y1 = tube_y0 + CF_Tube_Len;
// Full square rod, unconditional
translate([v[0]-w/2, v[1], v[2]-w/2]) cube([w, CF_Tube_Len, w]);
// Check for tapered holes
if ((block_y0 >= tube_y0) && (block_y0 < tube_y1)) // Tube protrudes through start of block
hull() {
translate([v[0], block_y0, v[2]])
cube([taper_w, hull_epsilon*2, taper_w], center=true);
translate([v[0], block_y0+taper_length, v[2]])
cube([w, hull_epsilon*2, w], center=true);
}
if ((block_y1 <= tube_y1) && (block_y1 > tube_y0)) // Tube protrudes through end of block
hull() {
translate([v[0], block_y1-hull_epsilon, v[2]])
cube([taper_w, hull_epsilon*2, taper_w], center=true);
translate([v[0], block_y1-hull_epsilon-taper_length, v[2]])
cube([w, hull_epsilon*2, w], center=true);
}
// if (taper_x1) {
// hull() {
// translate([0, x1, 0])
// cube([w*taper_mul, hull_epsilon, w*taper_mul], center=true);
// translate([0, x1+(taper_length*taper_direction), 0])
// cube([w, hull_epsilon, w], center=true);
// }
// }
// if (taper_x2){
// hull() {
// translate([0, x2, 0])
// cube([w*taper_mul, hull_epsilon, w*taper_mul], center=true);
// translate([0, x2-(taper_length*taper_direction), 0])
// cube([w, hull_epsilon, w], center=true);
// }
// }
}

View File

@ -1,6 +1,7 @@
Fender_Scale_mm = 648; // Actually 25.5inch = 647.7mm
Classical_Normal_Scale_mm = 650; // about 25.59inch
Classical_Short_Scale_mm = 635; // = 25inch
Gibson_Scale_mm = 630; // 24.75inch = 628.65mm
Guitar_Scale_Length_mm = Fender_Scale_mm;
ln2 = ln(2);
@ -10,6 +11,8 @@ function mm_to_fret_number(mm) = -log2(mm/Guitar_Scale_Length_mm)*12;
function lerp(start, end, amount) = start + (end-start)*amount;
function clamp(minimum, value, maximum) = min(max(minimum, value), maximum);
function flatten(l) = [ for (a = l) for (b = a) b];
function tri_circumcenter(pts) =
let(
v0 = pts[1] - pts[0],
@ -42,6 +45,13 @@ module round_cube(size, r) {
}
}
module rotate_around(angles, pt) {
translate(pt)
rotate(angles)
translate(-pt)
children();
}
// We can't use Droid Sans Japanese because the rendering library is really dumb and will pick the wrong Droid Sans. CJK fonts must be singular files.
JP_Serif_Font = "New Tegomin";
JP_Sans_Font = "Yuji Boku";