From 6dbff74f2b656b7ad1619b5ea11bd81fcf6c85e1 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Wed, 19 Jun 2019 01:35:08 -0700 Subject: [PATCH] Rewrote bezier_segment_closest_point() algorithm to search all minima. --- beziers.scad | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/beziers.scad b/beziers.scad index cd1e547..661853f 100644 --- a/beziers.scad +++ b/beziers.scad @@ -114,19 +114,35 @@ function bezier_curve(curve,n) = [for(i=[0:1:n-1]) bez_point(curve, i/(n-1))]; // trace_bezier(bez, N=len(bez)-1); // color("red") translate(pt) sphere(r=1); // color("blue") translate(bez_point(bez,u)) sphere(r=1); -function bezier_segment_closest_point(curve, pt, max_err=0.01, u=0, end_u=1, step_u=undef, min_dist=undef, min_u=undef) = +function bezier_segment_closest_point(curve, pt, max_err=0.01, u=0, end_u=1) = let( - step = step_u == undef? (end_u-u)/(len(curve)*2) : step_u, - t_u = min(u, end_u), - dist = norm(bez_point(curve, t_u)-pt), - md = (min_dist==undef || dist(end_u-step/2))? ( - (step1? ( + let( + min_us = [ + for (minima = minima_ranges) + bezier_segment_closest_point(curve, pt, max_err=max_err, u=minima.x, end_u=minima.y) + ], + dists = [for (v=min_us) norm(bez_point(curve,v)-pt)], + min_i = min_index(dists) + ) min_us[min_i] + ) : let( + minima = minima_ranges[0], + p1 = bez_point(curve, minima.x), + p2 = bez_point(curve, minima.y), + err = norm(p2-p1) + ) err