1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-11 17:24:20 +02:00

add angle_threshold param

This commit is contained in:
Justin Lin
2021-02-11 14:31:28 +08:00
parent 66054ae603
commit cf359b04fe
3 changed files with 29 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ use <../__comm__/__to3d.scad>;
use <../__comm__/__to2d.scad>; use <../__comm__/__to2d.scad>;
use <../__comm__/__angy_angz.scad>; use <../__comm__/__angy_angz.scad>;
use <../bezier_curve.scad>; use <../bezier_curve.scad>;
use <../angle_between.scad>;
function _corner_ctrl_pts(round_d, p1, p2, p3) = function _corner_ctrl_pts(round_d, p1, p2, p3) =
let( let(
@@ -24,32 +25,34 @@ function _corner_ctrl_pts(round_d, p1, p2, p3) =
p2 - [dx2, dy2, dz2] p2 - [dx2, dy2, dz2]
]; ];
function _bezier_corner(round_d, t_step, p1, p2, p3) = function _bezier_corner(round_d, t_step, p1, p2, p3) =
bezier_curve(t_step, _corner_ctrl_pts(round_d, p1, p2, p3)); bezier_curve(t_step, _corner_ctrl_pts(round_d, p1, p2, p3));
function _recursive_bezier_smooth(pts, round_d, t_step, leng) = function _recursive_bezier_smooth(pts, round_d, t_step, leng, angle_threshold) =
let(end_i = leng - 2) let(end_i = leng - 2)
[ [
for(i = 0; i < end_i; i = i + 1) for(i = 0; i < end_i; i = i + 1)
each _bezier_corner(round_d, t_step, pts[i], pts[i + 1], pts[i + 2]) each
angle_between(pts[i] - pts[i + 1], pts[i + 1] - pts[i + 2]) > angle_threshold ?
_bezier_corner(round_d, t_step, pts[i], pts[i + 1], pts[i + 2]) :
[pts[i + 1]]
]; ];
function _bezier_smooth_impl(path_pts, round_d, t_step, closed) = function _bezier_smooth_impl(path_pts, round_d, t_step, closed, angle_threshold) =
let( let(
pts = len(path_pts[0]) == 3 ? path_pts : [for(p = path_pts) __to3d(p)], pts = len(path_pts[0]) == 3 ? path_pts : [for(p = path_pts) __to3d(p)],
leng = len(pts), leng = len(pts),
middle_pts = _recursive_bezier_smooth(pts, round_d, t_step, leng), middle_pts = _recursive_bezier_smooth(pts, round_d, t_step, leng, angle_threshold),
pth_pts = closed ? pth_pts = closed ?
concat( concat(
_recursive_bezier_smooth( _recursive_bezier_smooth(
[pts[leng - 1], pts[0], pts[1]], [pts[leng - 1], pts[0], pts[1]],
round_d, t_step, 3 round_d, t_step, 3, angle_threshold
), ),
middle_pts, middle_pts,
_recursive_bezier_smooth( _recursive_bezier_smooth(
[pts[leng - 2], pts[leng - 1], pts[0]], [pts[leng - 2], pts[leng - 1], pts[0]],
round_d, t_step, 3 round_d, t_step, 3, angle_threshold
) )
) : ) :
concat( concat(

View File

@@ -10,5 +10,5 @@
use <_impl/_bezier_smooth_impl.scad>; use <_impl/_bezier_smooth_impl.scad>;
function bezier_smooth(path_pts, round_d, t_step = 0.1, closed = false) = function bezier_smooth(path_pts, round_d, t_step = 0.1, closed = false, angle_threshold = 0) =
_bezier_smooth_impl(path_pts, round_d, t_step, closed); _bezier_smooth_impl(path_pts, round_d, t_step, closed, angle_threshold);

View File

@@ -39,5 +39,21 @@ module test_bezier_smooth_closed() {
assertEqualPoints(expected, actual); assertEqualPoints(expected, actual);
} }
module test_bezier_smooth_angle_threshold() {
echo("==== test_bezier_smooth_angle_threshold ====");
round_d = 15;
path_pts = [
[0, 0, 0],
[0, 40, 0],
[0, 60, 0],
[0, 70, 1]
];
assert(path_pts == bezier_smooth(path_pts, round_d, angle_threshold = 15));
}
test_bezier_smooth_no_closed(); test_bezier_smooth_no_closed();
test_bezier_smooth_closed(); test_bezier_smooth_closed();
test_bezier_smooth_angle_threshold();