From 6448782a5317473100bbc90faf520377a3c2a6fb Mon Sep 17 00:00:00 2001 From: Alex Matulich Date: Sat, 4 Jan 2025 21:05:44 -0800 Subject: [PATCH] Update paths.scad paths.scad should no longer be part of this PR, it should be unchanged. Removed stuff that was added in the first commit. --- paths.scad | 78 ------------------------------------------------------ 1 file changed, 78 deletions(-) diff --git a/paths.scad b/paths.scad index 146191c..eb04f18 100644 --- a/paths.scad +++ b/paths.scad @@ -1246,82 +1246,4 @@ function _assemble_path_fragments(fragments, eps=EPSILON, _finished=[]) = ); -/// Internal function: _bend_path_corner() -/// Usage: -/// _bend_path_corner(three_point_path, [sharpness], [cutlimit], [splinesteps], [midpoint]); -/// Description: -/// Used by squircle() in shapes2d.scad and curvy_path() in rounding.scad -/// Given a path with three points [p1, p2, p3] (2D or 3D), return a subdivided path that curves around from p1 to p3, with the sharpness parameter determining how close to a perfect circle (sharpness=0) or the p2 corner (sharpness=1) the path is from the shortest leg, with the amount of corner lopped off limited by cutlimit. The longer leg is stretched appropriately. -/// The error in using a cubic bezier curve to approximate a circular arc is about 0.00026 for a unit circle, with zero error at the endpoint and the corner bisector. -/// Arguments: -/// p = List of 3 points [p1, p2, p3]. The points may be 2D or 3D. -/// sharpness = curve is circular (sharpness=0) or sharp to the corner (sharpness=1) or anywhere in between -/// cutlimit = optionally constrain the curved path to be no farther than this from the corner -/// splinesteps = number of steps to use for each half of the corner -function _bend_path_corner(p, sharpness=0.5, cutlimit=999999, splinesteps=10, midpoint=[true,true]) = - sharpness==1 || cutlimit==0 ? [p[1]] -: let( - p2 = p[1], - p1 = midpoint[0] ? 0.5*(p[0]+p2) : p[0], - p3 = midpoint[1] ? 0.5*(p2+p[2]) : p[2], - a0 = 0.5*vector_angle(p1, p2, p3), - d1 = norm(p1-p2), - d3 = norm(p3-p2), - tana = tan(a0), - rmin = min(d1, d3) * tana, - rmax = max(d1, d3) * tana, - // A "perfect" unit circle quadrant constructed from cubic bezier points [1,0], [1,d], [d,1], [0,1], with d=0.55228474983 has exact radius=1 at 0°, 45°, and 90°, with a maximum radius (at 22.5° and 67.5°) of 1.00026163152; nearly a perfect circle arc. - fleg = let(a2=a0*a0) - // model of "perfect" circle leg lengths for a bezier unit circle arc depending on arc angle a0; the model error is ~1e-5 - -4.4015E-08 * a2*a0 // tiny term, but reduces error by an order of magnitude - +0.0000113366 * a2 - -0.00680018 * a0 - +0.552244, - leglenmin = rmin * fleg, - leglenmax = rmax * fleg, - cp = circle_2tangents(rmin, p1, p2, p3)[0], // circle center - middir = unit(cp-p2), // unit vector from corner pointing to circle center - bzmid = cp - rmin*middir, // location of bezier point joining both halves of curve - maxcut = norm(bzmid-p2), // maximum possible distance from corner to curve - sharp = max(sharpness, 1-min(1, cutlimit/maxcut)), - - bzdist = maxcut * (1-sharp), // distance from corner to tip of curve - cornerlegmin = min(leglenmin, bzdist*tana), - cornerlegmax = min(leglenmax, bzdist*tana), - p21unit = unit(p1-p2), - p23unit = unit(p3-p2), - midto12unit = unit(p21unit-p23unit), - // bezier points around the corner p1,p2,p3 (p2 is the vertex): - // bz0 is p1 - // bz1 is on same leg as p1 - // bz2 is on line perpendicular to bisector for first half of curve - // bz3 is bezier start/end point on the corner bisector - // bz4 is on line perpendicular to bisector for second half of curve - // bz5 is on same leg as p3 - // bz6 is p3 - bz3 = p2 + middir * bzdist, // center control point - bz2 = bz3 + midto12unit*(d1