GuitarModels/common.scad

117 lines
3.8 KiB
OpenSCAD

PBass_Scale_mm = 865; // Actually 34inch = 863.6mm
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);
function log2(x) = ln(x)/ln2;
function fret_scale_length(n) = $guitar_scale_length_mm * 2^(-n/12);
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],
v1 = pts[2] - pts[1],
d0 = (pts[1] + pts[0])/2 * v0,
d1 = (pts[2] + pts[1])/2 * v1,
det = -cross(v0, v1)
)
[cross([d1, d0], [v1.y, v0.y]), cross([d0, d1], [v0.x, v1.x])] / det;
// Create a circle containing all 3 points, then plot the arc between the first two points
function arc_points(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_end = atan2(normalized1[1], normalized1[0]),
a_sweep = a_end - a_start,
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;
module sequential_hull() {
// given sequential_hull() {a b c d}, do hull {a b} hull {b c} hull {c d}, etc.
for (i = [0:$children-2]) hull() {
children(i);
children(i+1);
}
}
module round_cube(size, r) {
translate([r, r, r]) minkowski() {
cube(size-[r*2,r*2,r*2]);
sphere(r=r, $fn=72);
}
}
module rotate_around(angles, pt) {
translate(pt)
rotate(angles)
translate(-pt)
children();
}
module screw_hole_lobe(ID, OD, lobes=3) {
difference() {
circle(d=OD);
for (a=[0:360/lobes:360])
translate((OD/2)*[cos(a), sin(a)])
circle(d=OD-ID);
}
}
module circle_outer(d) {
// Regular circle inscribes, this circumscribes
$fn = (is_undef($fn) || $fn<3) ? 72 : $fn;
fudge = 1/cos(180/$fn);
circle(d=d*fudge);
}
module cylinder_outer(d, h, center=false, d2=undef) {
// Regular circle inscribes, this circumscribes
$fn = (is_undef($fn) || $fn<3) ? 72 : $fn;
fudge = 1/cos(180/$fn);
if (is_undef(d2)) {
cylinder(d=d*fudge, h=h, center=center);
} else {
cylinder(d1=d*fudge, d2=d2*fudge, h=h, center=center);
}
}
module cylinder_beak(d, h, beak=0.75) {
// A cylinder with a beak to take seams. This helps improve tolerances as seams often expand a little bit and ruin the fit.
// Since we only use it for holes, it will be a cylinder_outer as well
cylinder_outer(d=d, h=h);
// beak notch for seams
translate([0, d/2-beak*0.25, h/2]) rotate([0,0,45]) cube([beak, beak, h], center=true);
}
// 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";
JP_Fat_Sans_Font = ["Potta One", "Yusei Magic"];
JP_Light_Sans_Fonts = ["Hachi Maru Pop", "MotoyaLMaru", "Rounded MPlus 1c"];