1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-08-09 08:56:29 +02:00

Added bezier_join().

Moved path_length() from sweep.scad to maths.scad.
This commit is contained in:
Chris Palmer
2022-02-23 11:53:02 +00:00
parent 76aa613093
commit 42fccc1afb
6 changed files with 39 additions and 5 deletions

View File

@@ -19,8 +19,13 @@
//
//! Bezier curves and function to get and adjust the length or minimum z point.
//!
//! `bezier_join()` joins two paths with a Bezier curve that starts tangential to the end of `path1` and ends tangential to the end of `path2`.
//! To do this the outer control points are the path ends and the inner two control points are along the tangents to the path ends.
//! The only degree of freedom is how far along those tangents, which are the `d` and optional `d2` parameters.
//
include <../global_defs.scad>
include <maths.scad>
function bezier(t, v) = //! Returns a point at distance `t` [0 - 1] along the curve with control points `v`
(len(v) > 2) ? bezier(t, [for (i = [0 : len(v) - 2]) v[i] * (1 - t) + v[i + 1] * (t)])
@@ -55,3 +60,16 @@ function adjust_bezier_z(v, z, eps = 0.001, r1 = 1, r2 = 1.5, z1, z2) = //! Adju
: let(r = r1 + (z - z1) * (r2 - r1) / (z2 - z1))
abs(r - r1) < abs(r - r2) ? adjust_bezier_z(v, z, eps, r, r1, undef, z1)
: adjust_bezier_z(v, z, eps, r, r2, undef, z2);
function bezier_join(path1, path2, d, d2 = undef) = let( //! Join two paths with a Bezier curve, control points are the path ends are `d` and `d2` from the ends in the same direction.
d2 = is_undef(d2) ? d : d2,
l = len(path1),
p0 = path1[l - 1],
p1 = p0 + unit(p0 - path1[l - 2]) * d,
p3 = path2[0],
p2 = p3 + unit(path2[0] - path2[1]) * d2,
v = [p0, p1, p2, p3],
segs = path_length(v) / $fs,
path = [for(i = [1 : segs - 1], t = i / segs) bezier(t, v)],
len = len(path)
) concat(path1, path, path2);

View File

@@ -187,3 +187,7 @@ function cubic_real_roots(a, b, c, d) = //! Returns real roots of cubic equation
) roots == 1 ? [x] :
roots == 2 ? [3 * q /p + inflection, -3 * q / p / 2 + inflection] :
[for(i = [0 : roots - 1]) 2 * sqrt(-p / 3) * cos(acos(3 * q * sqrt(-3 / p) / p / 2) - i * 120) + inflection];
function path_length(path, i = 0, length = 0) = //! Calculated the length along a path
i >= len(path) - 1 ? length
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));

View File

@@ -177,10 +177,6 @@ module sweep(path, profile, loop = false, twist = 0, convexity = 1) { //! Draw a
polyhedron(points = mesh[0], faces = mesh[1], convexity = convexity);
}
function path_length(path, i = 0, length = 0) = //! Calculated the length along a path
i >= len(path) - 1 ? length
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));
function circle_points(r = 1, z = 0, dir = -1) = //! Generate the points of a circle, setting z makes a single turn spiral
let(sides = r2sides(r))
[for(i = [0 : sides - 1]) let(a = dir * i * 360 / sides) [r * cos(a), r * sin(a), z * i / sides]];