mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-12-30 03:58:04 +00:00
Update paths.scad
This commit is contained in:
parent
5a06450320
commit
270cc2fe62
1 changed files with 23 additions and 19 deletions
42
paths.scad
42
paths.scad
|
|
@ -15,6 +15,10 @@
|
|||
// FileFootnotes: STD=Included in std.scad
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
_BOSL2_PATHS = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOSL2_NO_STD_WARNING) ?
|
||||
echo("Warning: paths.scad included without std.scad; dependencies may be missing\nSet BOSL2_NO_STD_WARNING = true to mute this warning.") true : true;
|
||||
|
||||
|
||||
// Section: Utility Functions
|
||||
// Definitions:
|
||||
// Point|Points = A list of numbers, also called a vector. Usually has length 2 or 3 to represent points in the place on points in space.
|
||||
|
|
@ -146,8 +150,8 @@ function _path_select(path, s1, u1, s2, u2, closed=false) =
|
|||
// Arguments:
|
||||
// path = A path of any dimension or a 1-region
|
||||
// closed = treat as closed polygon. Default: false
|
||||
// eps = Largest positional variance allowed. Default: `EPSILON` (1-e9)
|
||||
function path_merge_collinear(path, closed, eps=EPSILON) =
|
||||
// eps = Largest positional variance allowed. Default: `_EPSILON` (1-e9)
|
||||
function path_merge_collinear(path, closed, eps=_EPSILON) =
|
||||
is_1region(path) ? path_merge_collinear(path[0], default(closed,true), eps) :
|
||||
let(closed=default(closed,false))
|
||||
assert(is_bool(closed))
|
||||
|
|
@ -258,7 +262,7 @@ function path_length_fractions(path, closed) =
|
|||
/// Arguments:
|
||||
/// path = The path to find self intersections of.
|
||||
/// closed = If true, treat path like a closed polygon. Default: true
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `EPSILON` (1e-9)
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `_EPSILON` (1e-9)
|
||||
/// Example(2D):
|
||||
/// path = [
|
||||
/// [-100,100], [0,-50], [100,100], [100,-100], [0,50], [-100,-100]
|
||||
|
|
@ -267,7 +271,7 @@ function path_length_fractions(path, closed) =
|
|||
/// // isects == [[[-33.3333, 0], 0, 0.666667, 4, 0.333333], [[33.3333, 0], 1, 0.333333, 3, 0.666667]]
|
||||
/// stroke(path, closed=true, width=1);
|
||||
/// for (isect=isects) translate(isect[0]) color("blue") sphere(d=10);
|
||||
function _path_self_intersections(path, closed=true, eps=EPSILON) =
|
||||
function _path_self_intersections(path, closed=true, eps=_EPSILON) =
|
||||
let(
|
||||
path = closed ? list_wrap(path,eps=eps) : path,
|
||||
plen = len(path)
|
||||
|
|
@ -687,8 +691,8 @@ function _err_resample(path, maxerr, n, i1=0, i2=2, resultidx=[0], iter=0) =
|
|||
// Arguments:
|
||||
// path = 2D path or 1-region
|
||||
// closed = set to true to treat path as a polygon. Default: false
|
||||
// eps = Epsilon error value used for determine if points coincide. Default: `EPSILON` (1e-9)
|
||||
function is_path_simple(path, closed, eps=EPSILON) =
|
||||
// eps = Epsilon error value used for determine if points coincide. Default: `_EPSILON` (1e-9)
|
||||
function is_path_simple(path, closed, eps=_EPSILON) =
|
||||
is_1region(path) ? is_path_simple(path[0], default(closed,true), eps) :
|
||||
let(closed=default(closed,false))
|
||||
assert(is_path(path, 2),"\nMust give a 2D path.")
|
||||
|
|
@ -820,7 +824,7 @@ function path_normals(path, tangents, closed) =
|
|||
)
|
||||
dim == 2 ? [tangents[i].y,-tangents[i].x]
|
||||
: let( v=cross(cross(pts[1]-pts[0], pts[2]-pts[0]),tangents[i]))
|
||||
assert(norm(v)>EPSILON, "\n3D path contains collinear points.")
|
||||
assert(norm(v)>_EPSILON, "\n3D path contains collinear points.")
|
||||
unit(v)
|
||||
];
|
||||
|
||||
|
|
@ -939,8 +943,8 @@ function path_cut(path,cutdist,closed) =
|
|||
let(closed=default(closed,false))
|
||||
assert(is_bool(closed))
|
||||
assert(is_vector(cutdist))
|
||||
assert(last(cutdist)<path_length(path,closed=closed)-EPSILON,"\nCut distances must be smaller than the path length.")
|
||||
assert(cutdist[0]>EPSILON, "\nCut distances must be strictly positive.")
|
||||
assert(last(cutdist)<path_length(path,closed=closed)-_EPSILON,"\nCut distances must be smaller than the path length.")
|
||||
assert(cutdist[0]>_EPSILON, "\nCut distances must be strictly positive.")
|
||||
let(
|
||||
cutlist = path_cut_points(path,cutdist,closed=closed)
|
||||
)
|
||||
|
|
@ -1122,12 +1126,12 @@ function _cut_to_seg_u_form(pathcut, path, closed) =
|
|||
// Arguments:
|
||||
// path = A 2D path or a 1-region.
|
||||
// closed = If true, treat path as a closed polygon. Default: true
|
||||
// eps = Acceptable variance. Default: `EPSILON` (1e-9)
|
||||
// eps = Acceptable variance. Default: `_EPSILON` (1e-9)
|
||||
// Example(2D,NoAxes):
|
||||
// path = [ [-100,100], [0,-50], [100,100], [100,-100], [0,50], [-100,-100] ];
|
||||
// paths = split_path_at_self_crossings(path);
|
||||
// rainbow(paths) stroke($item, closed=false, width=3);
|
||||
function split_path_at_self_crossings(path, closed=true, eps=EPSILON) =
|
||||
function split_path_at_self_crossings(path, closed=true, eps=_EPSILON) =
|
||||
let(path = force_path(path))
|
||||
assert(is_path(path,2), "\nMust give a 2D path.")
|
||||
assert(is_bool(closed))
|
||||
|
|
@ -1160,7 +1164,7 @@ function split_path_at_self_crossings(path, closed=true, eps=EPSILON) =
|
|||
];
|
||||
|
||||
|
||||
function _tag_self_crossing_subpaths(path, nonzero, closed=true, eps=EPSILON) =
|
||||
function _tag_self_crossing_subpaths(path, nonzero, closed=true, eps=_EPSILON) =
|
||||
let(
|
||||
subpaths = split_path_at_self_crossings(
|
||||
path, closed=true, eps=eps
|
||||
|
|
@ -1193,7 +1197,7 @@ function _tag_self_crossing_subpaths(path, nonzero, closed=true, eps=EPSILON) =
|
|||
// Arguments:
|
||||
// poly = a 2D polygon or 1-region
|
||||
// nonzero = If true use the nonzero method for checking if a point is in a polygon. Otherwise use the even-odd method. Default: false
|
||||
// eps = The epsilon error value to determine whether two points coincide. Default: `EPSILON` (1e-9)
|
||||
// eps = The epsilon error value to determine whether two points coincide. Default: `_EPSILON` (1e-9)
|
||||
// Example(2D,NoAxes): This cross-crossing polygon breaks up into its 3 components (regardless of the value of nonzero).
|
||||
// poly = [
|
||||
// [-100,100], [0,-50], [100,100],
|
||||
|
|
@ -1242,7 +1246,7 @@ function _tag_self_crossing_subpaths(path, nonzero, closed=true, eps=EPSILON) =
|
|||
// polygon(poly);
|
||||
// right(27)rainbow(polygon_parts(poly)) polygon($item);
|
||||
// move([16,-14])rainbow(polygon_parts(poly,nonzero=true)) polygon($item);
|
||||
function polygon_parts(poly, nonzero=false, eps=EPSILON) =
|
||||
function polygon_parts(poly, nonzero=false, eps=_EPSILON) =
|
||||
let(poly = force_path(poly))
|
||||
assert(is_path(poly,2), "\nMust give 2D polygon.")
|
||||
assert(is_bool(nonzero))
|
||||
|
|
@ -1254,7 +1258,7 @@ function polygon_parts(poly, nonzero=false, eps=EPSILON) =
|
|||
) outregion;
|
||||
|
||||
|
||||
function _extreme_angle_fragment(seg, fragments, rightmost=true, eps=EPSILON) =
|
||||
function _extreme_angle_fragment(seg, fragments, rightmost=true, eps=_EPSILON) =
|
||||
!fragments? [undef, []] :
|
||||
let(
|
||||
delta = seg[1] - seg[0],
|
||||
|
|
@ -1298,8 +1302,8 @@ function _extreme_angle_fragment(seg, fragments, rightmost=true, eps=EPSILON) =
|
|||
/// fragments = List of paths to be assembled into complete polygons.
|
||||
/// rightmost = If true, assemble paths using rightmost turns. Leftmost if false.
|
||||
/// startfrag = The fragment to start with. Default: 0
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `EPSILON` (1e-9)
|
||||
function _assemble_a_path_from_fragments(fragments, rightmost=true, startfrag=0, eps=EPSILON) =
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `_EPSILON` (1e-9)
|
||||
function _assemble_a_path_from_fragments(fragments, rightmost=true, startfrag=0, eps=_EPSILON) =
|
||||
len(fragments)==0? [[],[]] :
|
||||
len(fragments)==1? [fragments[0],[]] :
|
||||
let(
|
||||
|
|
@ -1353,8 +1357,8 @@ function _assemble_a_path_from_fragments(fragments, rightmost=true, startfrag=0,
|
|||
/// Polygons with area < eps are discarded and not returned.
|
||||
/// Arguments:
|
||||
/// fragments = List of paths to be assembled into complete polygons.
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `EPSILON` (1e-9)
|
||||
function _assemble_path_fragments(fragments, eps=EPSILON, _finished=[]) =
|
||||
/// eps = The epsilon error value to determine whether two points coincide. Default: `_EPSILON` (1e-9)
|
||||
function _assemble_path_fragments(fragments, eps=_EPSILON, _finished=[]) =
|
||||
len(fragments)==0? _finished :
|
||||
let(
|
||||
minxidx = min_index([
|
||||
|
|
|
|||
Loading…
Reference in a new issue