mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 00:09:41 +00:00
Add "is" to geometry.scad predicates
This commit is contained in:
parent
ea7b947bcb
commit
d78eb5213e
8 changed files with 105 additions and 132 deletions
|
@ -217,7 +217,7 @@ function xy_to_polar(x,y=undef) = let(
|
|||
// stroke(xypath,closed=true);
|
||||
function project_plane(plane,p) =
|
||||
is_matrix(plane,3,3) && is_undef(p) ? // no data, 3 points given
|
||||
assert(!collinear(plane),"Points defining the plane must not be collinear")
|
||||
assert(!is_collinear(plane),"Points defining the plane must not be collinear")
|
||||
let(
|
||||
v = plane[2]-plane[0],
|
||||
y = unit(plane[1]-plane[0]), // y axis goes to point b
|
||||
|
@ -242,7 +242,7 @@ function project_plane(plane,p) =
|
|||
[for(plist=p) project_plane(plane,plist)]
|
||||
: assert(is_vector(p,3) || is_path(p,3),str("Data must be a 3d point, path, region, vnf or bezier patch",p))
|
||||
is_matrix(plane,3,3) ?
|
||||
assert(!collinear(plane),"Points defining the plane must not be collinear")
|
||||
assert(!is_collinear(plane),"Points defining the plane must not be collinear")
|
||||
let(
|
||||
v = plane[2]-plane[0],
|
||||
y = unit(plane[1]-plane[0]), // y axis goes to point b
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
// Section: Lines, Rays, and Segments
|
||||
|
||||
// Function: point_on_line()
|
||||
// Function: is_point_on_line()
|
||||
// Usage:
|
||||
// pt = point_on_line(point, line, [bounded], [eps]);
|
||||
// pt = is_point_on_line(point, line, [bounded], [eps]);
|
||||
// Topics: Geometry, Points, Segments
|
||||
// Description:
|
||||
// Determine if the point is on the line segment, ray or segment defined by the two between two points.
|
||||
|
@ -25,7 +25,7 @@
|
|||
// line = Array of two points defining the line, ray, or segment to test against.
|
||||
// bounded = boolean or list of two booleans defining endpoint conditions for the line. If false treat the line as an unbounded line. If true treat it as a segment. If [true,false] treat as a ray, based at the first endpoint. Default: false
|
||||
// eps = Tolerance in geometric comparisons. Default: `EPSILON` (1e-9)
|
||||
function point_on_line(point, line, bounded=false, eps=EPSILON) =
|
||||
function is_point_on_line(point, line, bounded=false, eps=EPSILON) =
|
||||
assert( is_finite(eps) && (eps>=0), "The tolerance should be a non-negative value." )
|
||||
point_line_distance(point, line, bounded)<eps;
|
||||
|
||||
|
@ -66,9 +66,9 @@ function _point_left_of_line2d(point, line) =
|
|||
cross(line[0]-point, line[1]-line[0]);
|
||||
|
||||
|
||||
// Function: collinear()
|
||||
// Function: is_collinear()
|
||||
// Usage:
|
||||
// test = collinear(a, [b, c], [eps]);
|
||||
// test = is_collinear(a, [b, c], [eps]);
|
||||
// Topics: Geometry, Points, Collinearity
|
||||
// Description:
|
||||
// Returns true if the points `a`, `b` and `c` are co-linear or if the list of points `a` is collinear.
|
||||
|
@ -77,7 +77,7 @@ function _point_left_of_line2d(point, line) =
|
|||
// b = Second point or undef; it should be undef if `c` is undef
|
||||
// c = Third point or undef.
|
||||
// eps = Tolerance in geometric comparisons. Default: `EPSILON` (1e-9)
|
||||
function collinear(a, b, c, eps=EPSILON) =
|
||||
function is_collinear(a, b, c, eps=EPSILON) =
|
||||
assert( is_path([a,b,c],dim=undef)
|
||||
|| ( is_undef(b) && is_undef(c) && is_path(a,dim=undef) ),
|
||||
"Input should be 3 points or a list of points with same dimension.")
|
||||
|
@ -336,7 +336,7 @@ function line_from_points(points, fast=false, eps=EPSILON) =
|
|||
assert( is_finite(eps) && (eps>=0), "The tolerance should be a non-negative value." )
|
||||
let( pb = furthest_point(points[0],points) )
|
||||
norm(points[pb]-points[0])<eps*max(norm(points[pb]),norm(points[0])) ? undef :
|
||||
fast || collinear(points)
|
||||
fast || is_collinear(points)
|
||||
? [points[pb], points[0]]
|
||||
: undef;
|
||||
|
||||
|
@ -345,16 +345,16 @@ function line_from_points(points, fast=false, eps=EPSILON) =
|
|||
// Section: Planes
|
||||
|
||||
|
||||
// Function: coplanar()
|
||||
// Function: is_coplanar()
|
||||
// Usage:
|
||||
// test = coplanar(points,[eps]);
|
||||
// test = is_coplanar(points,[eps]);
|
||||
// Topics: Geometry, Coplanarity
|
||||
// Description:
|
||||
// Returns true if the given 3D points are non-collinear and are on a plane.
|
||||
// Arguments:
|
||||
// points = The points to test.
|
||||
// eps = Tolerance in geometric comparisons. Default: `EPSILON` (1e-9)
|
||||
function coplanar(points, eps=EPSILON) =
|
||||
function is_coplanar(points, eps=EPSILON) =
|
||||
assert( is_path(points,dim=3) , "Input should be a list of 3D points." )
|
||||
assert( is_finite(eps) && eps>=0, "The tolerance should be a non-negative value." )
|
||||
len(points)<=2 ? false
|
||||
|
@ -539,7 +539,7 @@ function plane_from_polygon(poly, fast=false, eps=EPSILON) =
|
|||
let(
|
||||
plane = plane_from_normal(poly_normal, poly[0])
|
||||
)
|
||||
fast? plane: points_on_plane(poly, plane, eps=eps)? plane: [];
|
||||
fast? plane: are_points_on_plane(poly, plane, eps=eps)? plane: [];
|
||||
|
||||
|
||||
// Function: plane_normal()
|
||||
|
@ -926,9 +926,9 @@ function _pointlist_greatest_distance(points,plane) =
|
|||
abs(max( max(pt_nrm) - plane[3], -min(pt_nrm) + plane[3])) / norm(normal);
|
||||
|
||||
|
||||
// Function: points_on_plane()
|
||||
// Function: are_points_on_plane()
|
||||
// Usage:
|
||||
// test = points_on_plane(points, plane, [eps]);
|
||||
// test = are_points_on_plane(points, plane, [eps]);
|
||||
// Topics: Geometry, Planes, Points
|
||||
// Description:
|
||||
// Returns true if the given 3D points are on the given plane.
|
||||
|
@ -936,14 +936,14 @@ function _pointlist_greatest_distance(points,plane) =
|
|||
// plane = The plane to test the points on.
|
||||
// points = The list of 3D points to test.
|
||||
// eps = Tolerance in geometric comparisons. Default: `EPSILON` (1e-9)
|
||||
function points_on_plane(points, plane, eps=EPSILON) =
|
||||
function are_points_on_plane(points, plane, eps=EPSILON) =
|
||||
assert( _valid_plane(plane), "Invalid plane." )
|
||||
assert( is_matrix(points,undef,3) && len(points)>0, "Invalid pointlist." ) // using is_matrix it accepts len(points)==1
|
||||
assert( is_finite(eps) && eps>=0, "The tolerance should be a positive number." )
|
||||
_pointlist_greatest_distance(points,plane) < eps;
|
||||
|
||||
|
||||
// Function: above_plane()
|
||||
// Function: is_above_plane()
|
||||
// Usage:
|
||||
// test = in_front_of_plane(plane, point);
|
||||
// Topics: Geometry, Planes
|
||||
|
@ -955,7 +955,7 @@ function points_on_plane(points, plane, eps=EPSILON) =
|
|||
// Arguments:
|
||||
// plane = The [A,B,C,D] coefficients for the first plane equation `Ax+By+Cz=D`.
|
||||
// point = The 3D point to test.
|
||||
function above_plane(plane, point) =
|
||||
function is_above_plane(plane, point) =
|
||||
point_plane_distance(plane, point) > EPSILON;
|
||||
|
||||
|
||||
|
@ -1074,7 +1074,7 @@ function circle_2tangents(pt1, pt2, pt3, r, d, tangents=false) =
|
|||
"Invalid input points." )
|
||||
is_undef(pt2)
|
||||
? circle_2tangents(pt1[0], pt1[1], pt1[2], r=r, tangents=tangents)
|
||||
: collinear(pt1, pt2, pt3)? undef :
|
||||
: is_collinear(pt1, pt2, pt3)? undef :
|
||||
let(
|
||||
v1 = unit(pt1 - pt2),
|
||||
v2 = unit(pt3 - pt2),
|
||||
|
@ -1159,7 +1159,7 @@ function circle_3points(pt1, pt2, pt3) =
|
|||
: assert( is_vector(pt1) && is_vector(pt2) && is_vector(pt3)
|
||||
&& max(len(pt1),len(pt2),len(pt3))<=3 && min(len(pt1),len(pt2),len(pt3))>=2,
|
||||
"Invalid point(s)." )
|
||||
collinear(pt1,pt2,pt3)? [undef,undef,undef] :
|
||||
is_collinear(pt1,pt2,pt3)? [undef,undef,undef] :
|
||||
let(
|
||||
v = [ point3d(pt1), point3d(pt2), point3d(pt3) ], // triangle vertices
|
||||
ed = [for(i=[0:2]) v[(i+1)%3]-v[i] ], // triangle edge vectors
|
||||
|
@ -1530,7 +1530,7 @@ function point_in_polygon(point, poly, nonzero=false, eps=EPSILON) =
|
|||
for (i = [0:1:len(poly)-1])
|
||||
let( seg = select(poly,i,i+1) )
|
||||
if (!approx(seg[0],seg[1],eps) )
|
||||
point_on_line(point, seg, SEGMENT, eps=eps)? 1:0
|
||||
is_point_on_line(point, seg, SEGMENT, eps=eps)? 1:0
|
||||
]
|
||||
)
|
||||
sum(on_brd) > 0? 0 :
|
||||
|
@ -1752,6 +1752,7 @@ function reverse_polygon(poly) =
|
|||
// Topics: Geometry, Polygons
|
||||
// Description:
|
||||
// Given a polygon `poly`, rotates the point ordering so that the first point in the polygon path is the one at index `i`.
|
||||
// This is identical to `list_rotate` except that it checks for doubled endpoints and removed them if present.
|
||||
// Arguments:
|
||||
// poly = The list of points in the polygon path.
|
||||
// i = The index of the point to shift to the front of the path.
|
||||
|
@ -1762,24 +1763,6 @@ function polygon_shift(poly, i) =
|
|||
list_rotate(cleanup_path(poly), i);
|
||||
|
||||
|
||||
// Function: polygon_shift_to_closest_point()
|
||||
// Usage:
|
||||
// newpoly = polygon_shift_to_closest_point(path, pt);
|
||||
// Topics: Geometry, Polygons
|
||||
// Description:
|
||||
// Given a polygon `poly`, rotates the point ordering so that the first point in the path is the one closest to the given point `pt`.
|
||||
// Arguments:
|
||||
// poly = The list of points in the polygon path.
|
||||
// pt = The reference point.
|
||||
function polygon_shift_to_closest_point(poly, pt) =
|
||||
assert(is_vector(pt), "Invalid point." )
|
||||
assert(is_path(poly,dim=len(pt)), "Invalid polygon or incompatible dimension with the point." )
|
||||
let(
|
||||
poly = cleanup_path(poly),
|
||||
dists = [for (p=poly) norm(p-pt)],
|
||||
closest = min_index(dists)
|
||||
) select(poly,closest,closest+len(poly)-1);
|
||||
|
||||
|
||||
// Function: reindex_polygon()
|
||||
// Usage:
|
||||
|
|
|
@ -186,7 +186,7 @@ function hull3d_faces(points) =
|
|||
remaining = [for (i = [0:1:len(points)-1]) if (i!=a && i!=b && i!=c && i!=d) i],
|
||||
// Build an initial tetrahedron.
|
||||
// Swap b, c if d is in front of triangle t.
|
||||
ifop = above_plane(plane, points[d]),
|
||||
ifop = is_above_plane(plane, points[d]),
|
||||
bc = ifop? [c,b] : [b,c],
|
||||
b = bc[0],
|
||||
c = bc[1],
|
||||
|
@ -245,7 +245,7 @@ function _remove_internal_edges(halfedges) = [
|
|||
];
|
||||
|
||||
function _find_first_noncoplanar(plane, points, i=0) =
|
||||
(i >= len(points) || !points_on_plane([points[i]],plane))? i :
|
||||
(i >= len(points) || !are_points_on_plane([points[i]],plane))? i :
|
||||
_find_first_noncoplanar(plane, points, i+1);
|
||||
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ function simplify_path(path, eps=EPSILON) =
|
|||
indices = [
|
||||
0,
|
||||
for (i=[1:1:len(path)-2])
|
||||
if (!collinear(path[i-1], path[i], path[i+1], eps=eps)) i,
|
||||
if (!is_collinear(path[i-1], path[i], path[i+1], eps=eps)) i,
|
||||
len(path)-1
|
||||
]
|
||||
) [for (i=indices) path[i]];
|
||||
|
@ -148,7 +148,7 @@ function simplify_path_indexed(points, indices, eps=EPSILON) =
|
|||
i1 = indices[i-1],
|
||||
i2 = indices[i],
|
||||
i3 = indices[i+1]
|
||||
) if (!collinear(points[i1], points[i2], points[i3], eps=eps))
|
||||
) if (!is_collinear(points[i1], points[i2], points[i3], eps=eps))
|
||||
indices[i]
|
||||
],
|
||||
indices[len(indices)-1]
|
||||
|
@ -604,7 +604,7 @@ function path_add_jitter(path, dist=1/512, closed=true) =
|
|||
path[0],
|
||||
for (i=idx(path,s=1,e=closed?-1:-2)) let(
|
||||
n = line_normal([path[i-1],path[i]])
|
||||
) path[i] + n * (collinear(select(path,i-1,i+1))? (dist * ((i%2)*2-1)) : 0),
|
||||
) path[i] + n * (is_collinear(select(path,i-1,i+1))? (dist * ((i%2)*2-1)) : 0),
|
||||
if (!closed) last(path)
|
||||
];
|
||||
|
||||
|
@ -1004,7 +1004,7 @@ function _path_cuts_normals(path, cuts, dirs, closed=false) =
|
|||
// to define the plane of the path.
|
||||
function _path_plane(path, ind, i,closed) =
|
||||
i<(closed?-1:0) ? undef :
|
||||
!collinear(path[ind],path[ind-1], select(path,i))?
|
||||
!is_collinear(path[ind],path[ind-1], select(path,i))?
|
||||
[select(path,i)-path[ind-1],path[ind]-path[ind-1]] :
|
||||
_path_plane(path, ind, i-1);
|
||||
|
||||
|
|
|
@ -1865,16 +1865,16 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b
|
|||
assert(jsvecok || jssingleok,
|
||||
str("Argument joint_sides is invalid. All entries must be nonnegative, and it must be a number, 2-vector, or a length ",N," list those."))
|
||||
assert(is_num(k_sides) || is_vector(k_sides,N), str("Curvature parameter k_sides must be a number or length ",N," vector"))
|
||||
assert(coplanar(bottom))
|
||||
assert(coplanar(top))
|
||||
assert(is_coplanar(bottom))
|
||||
assert(is_coplanar(top))
|
||||
assert(!is_num(k_sides) || (k_sides>=0 && k_sides<=1), "Curvature parameter k_sides must be in interval [0,1]")
|
||||
let(
|
||||
non_coplanar=[for(i=[0:N-1]) if (!coplanar(concat(select(top,i,i+1), select(bottom,i,i+1)))) [i,(i+1)%N]],
|
||||
non_coplanar=[for(i=[0:N-1]) if (!is_coplanar(concat(select(top,i,i+1), select(bottom,i,i+1)))) [i,(i+1)%N]],
|
||||
k_sides_vec = is_num(k_sides) ? repeat(k_sides, N) : k_sides,
|
||||
kbad = [for(i=[0:N-1]) if (k_sides_vec[i]<0 || k_sides_vec[i]>1) i],
|
||||
joint_sides_vec = jssingleok ? repeat(joint_sides,N) : joint_sides,
|
||||
top_collinear = [for(i=[0:N-1]) if (collinear(select(top,i-1,i+1))) i],
|
||||
bot_collinear = [for(i=[0:N-1]) if (collinear(select(bottom,i-1,i+1))) i]
|
||||
top_collinear = [for(i=[0:N-1]) if (is_collinear(select(top,i-1,i+1))) i],
|
||||
bot_collinear = [for(i=[0:N-1]) if (is_collinear(select(bottom,i-1,i+1))) i]
|
||||
)
|
||||
assert(non_coplanar==[], str("Side faces are non-coplanar at edges: ",non_coplanar))
|
||||
assert(top_collinear==[], str("Top has collinear or duplicated points at indices: ",top_collinear))
|
||||
|
@ -1940,14 +1940,14 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b
|
|||
vline = concat(select(subindex(top_patch[i],j),2,4),
|
||||
select(subindex(bot_patch[i],j),2,4))
|
||||
)
|
||||
if (!collinear(vline)) [i,j]],
|
||||
if (!is_collinear(vline)) [i,j]],
|
||||
//verify horiz edges
|
||||
verify_horiz=[for(i=[0:N-1], j=[0:4])
|
||||
let(
|
||||
hline_top = concat(select(top_patch[i][j],2,4), select(select(top_patch, i+1)[j],0,2)),
|
||||
hline_bot = concat(select(bot_patch[i][j],2,4), select(select(bot_patch, i+1)[j],0,2))
|
||||
)
|
||||
if (!collinear(hline_top) || !collinear(hline_bot)) [i,j]]
|
||||
if (!is_collinear(hline_top) || !is_collinear(hline_bot)) [i,j]]
|
||||
)
|
||||
assert(debug || top_intersections==[],
|
||||
"Roundovers interfere with each other on top face: either input is self intersecting or top joint length is too large")
|
||||
|
|
|
@ -618,7 +618,7 @@ function arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, l
|
|||
arc(N,cp=cp,r=r,start=atan2(v1.y,v1.x),angle=final_angle,wedge=wedge)
|
||||
) : (
|
||||
// Final case is arc passing through three points, starting at point[0] and ending at point[3]
|
||||
let(col = collinear(points[0],points[1],points[2]))
|
||||
let(col = is_collinear(points[0],points[1],points[2]))
|
||||
assert(!col, "Collinear inputs do not define an arc")
|
||||
let(
|
||||
cp = line_intersection(_normal_segment(points[0],points[1]),_normal_segment(points[1],points[2])),
|
||||
|
|
|
@ -6,8 +6,8 @@ include <../std.scad>
|
|||
|
||||
|
||||
|
||||
test_point_on_line();
|
||||
test_collinear();
|
||||
test_is_point_on_line();
|
||||
test_is_collinear();
|
||||
test_point_line_distance();
|
||||
test_segment_distance();
|
||||
test_line_normal();
|
||||
|
@ -33,9 +33,9 @@ test_plane_line_angle();
|
|||
test_plane_line_intersection();
|
||||
test_polygon_line_intersection();
|
||||
test_plane_intersection();
|
||||
test_coplanar();
|
||||
test_points_on_plane();
|
||||
test_above_plane();
|
||||
test_is_coplanar();
|
||||
test_are_points_on_plane();
|
||||
test_is_above_plane();
|
||||
test_circle_2tangents();
|
||||
test_circle_3points();
|
||||
test_circle_point_tangents();
|
||||
|
@ -44,7 +44,6 @@ test_noncollinear_triple();
|
|||
test_polygon_area();
|
||||
test_is_polygon_convex();
|
||||
test_polygon_shift();
|
||||
test_polygon_shift_to_closest_point();
|
||||
test_reindex_polygon();
|
||||
test_align_polygon();
|
||||
test_centroid();
|
||||
|
@ -223,7 +222,7 @@ module test__general_plane_line_intersection() {
|
|||
*test__general_plane_line_intersection();
|
||||
|
||||
|
||||
module test_points_on_plane() {
|
||||
module test_are_points_on_plane() {
|
||||
pts = [for(i=[0:40]) rands(-1,1,3) ];
|
||||
dir = rands(-10,10,3);
|
||||
normal0 = [1,2,3];
|
||||
|
@ -232,10 +231,10 @@ module test_points_on_plane() {
|
|||
plane = [each normal, normal*dir];
|
||||
prj_pts = plane_closest_point(plane,pts);
|
||||
info = info_str([["pts = ",pts],["dir = ",dir],["ang = ",ang]]);
|
||||
assert(points_on_plane(prj_pts,plane),info);
|
||||
assert(!points_on_plane(concat(pts,[normal-dir]),plane),info);
|
||||
assert(are_points_on_plane(prj_pts,plane),info);
|
||||
assert(!are_points_on_plane(concat(pts,[normal-dir]),plane),info);
|
||||
}
|
||||
*test_points_on_plane();
|
||||
*test_are_points_on_plane();
|
||||
|
||||
module test_plane_closest_point(){
|
||||
ang = rands(0,360,1)[0];
|
||||
|
@ -266,43 +265,43 @@ module test_line_from_points() {
|
|||
}
|
||||
*test_line_from_points();
|
||||
|
||||
module test_point_on_line() {
|
||||
assert(point_on_line([-15,0], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
assert(point_on_line([-10,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(point_on_line([-5,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(point_on_line([0,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(point_on_line([3,3], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
assert(point_on_line([5,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(point_on_line([10,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(point_on_line([15,0], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
module test_is_point_on_line() {
|
||||
assert(is_point_on_line([-15,0], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
assert(is_point_on_line([-10,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(is_point_on_line([-5,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(is_point_on_line([0,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(is_point_on_line([3,3], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
assert(is_point_on_line([5,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(is_point_on_line([10,0], [[-10,0], [10,0]],SEGMENT) == true);
|
||||
assert(is_point_on_line([15,0], [[-10,0], [10,0]],SEGMENT) == false);
|
||||
|
||||
assert(point_on_line([0,-15], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
assert(point_on_line([0,-10], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(point_on_line([0, -5], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(point_on_line([0, 0], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(point_on_line([3, 3], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
assert(point_on_line([0, 5], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(point_on_line([0, 10], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(point_on_line([0, 15], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([0,-15], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([0,-10], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([0, -5], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([0, 0], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([3, 3], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([0, 5], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([0, 10], [[0,-10], [0,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([0, 15], [[0,-10], [0,10]],SEGMENT) == false);
|
||||
|
||||
assert(point_on_line([-15,-15], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
assert(point_on_line([-10,-10], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(point_on_line([ -5, -5], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(point_on_line([ 0, 0], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(point_on_line([ 0, 3], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
assert(point_on_line([ 5, 5], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(point_on_line([ 10, 10], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(point_on_line([ 15, 15], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([-15,-15], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([-10,-10], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([ -5, -5], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([ 0, 0], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([ 0, 3], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
assert(is_point_on_line([ 5, 5], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([ 10, 10], [[-10,-10], [10,10]],SEGMENT) == true);
|
||||
assert(is_point_on_line([ 15, 15], [[-10,-10], [10,10]],SEGMENT) == false);
|
||||
|
||||
assert(point_on_line([10,10], [[0,0],[5,5]]) == true);
|
||||
assert(point_on_line([4,4], [[0,0],[5,5]]) == true);
|
||||
assert(point_on_line([-2,-2], [[0,0],[5,5]]) == true);
|
||||
assert(point_on_line([5,5], [[0,0],[5,5]]) == true);
|
||||
assert(point_on_line([10,10], [[0,0],[5,5]],RAY) == true);
|
||||
assert(point_on_line([0,0], [[0,0],[5,5]],RAY) == true);
|
||||
assert(point_on_line([3,3], [[0,0],[5,5]],RAY) == true);
|
||||
assert(is_point_on_line([10,10], [[0,0],[5,5]]) == true);
|
||||
assert(is_point_on_line([4,4], [[0,0],[5,5]]) == true);
|
||||
assert(is_point_on_line([-2,-2], [[0,0],[5,5]]) == true);
|
||||
assert(is_point_on_line([5,5], [[0,0],[5,5]]) == true);
|
||||
assert(is_point_on_line([10,10], [[0,0],[5,5]],RAY) == true);
|
||||
assert(is_point_on_line([0,0], [[0,0],[5,5]],RAY) == true);
|
||||
assert(is_point_on_line([3,3], [[0,0],[5,5]],RAY) == true);
|
||||
}
|
||||
*test_point_on_line();
|
||||
*test_is_point_on_line();
|
||||
|
||||
|
||||
module test__point_left_of_line2d() {
|
||||
|
@ -312,18 +311,18 @@ module test__point_left_of_line2d() {
|
|||
}
|
||||
test__point_left_of_line2d();
|
||||
|
||||
module test_collinear() {
|
||||
assert(collinear([-10,-10], [-15, -16], [10,10]) == false);
|
||||
assert(collinear([[-10,-10], [-15, -16], [10,10]]) == false);
|
||||
assert(collinear([-10,-10], [-15, -15], [10,10]) == true);
|
||||
assert(collinear([[-10,-10], [-15, -15], [10,10]]) == true);
|
||||
assert(collinear([-10,-10], [ -3, 0], [10,10]) == false);
|
||||
assert(collinear([-10,-10], [ 0, 0], [10,10]) == true);
|
||||
assert(collinear([-10,-10], [ 3, 0], [10,10]) == false);
|
||||
assert(collinear([-10,-10], [ 15, 15], [10,10]) == true);
|
||||
assert(collinear([-10,-10], [ 15, 16], [10,10]) == false);
|
||||
module test_is_collinear() {
|
||||
assert(is_collinear([-10,-10], [-15, -16], [10,10]) == false);
|
||||
assert(is_collinear([[-10,-10], [-15, -16], [10,10]]) == false);
|
||||
assert(is_collinear([-10,-10], [-15, -15], [10,10]) == true);
|
||||
assert(is_collinear([[-10,-10], [-15, -15], [10,10]]) == true);
|
||||
assert(is_collinear([-10,-10], [ -3, 0], [10,10]) == false);
|
||||
assert(is_collinear([-10,-10], [ 0, 0], [10,10]) == true);
|
||||
assert(is_collinear([-10,-10], [ 3, 0], [10,10]) == false);
|
||||
assert(is_collinear([-10,-10], [ 15, 15], [10,10]) == true);
|
||||
assert(is_collinear([-10,-10], [ 15, 16], [10,10]) == false);
|
||||
}
|
||||
*test_collinear();
|
||||
*test_is_collinear();
|
||||
|
||||
|
||||
module test_point_line_distance() {
|
||||
|
@ -730,26 +729,26 @@ module test_polygon_line_intersection() {
|
|||
*test_polygon_line_intersection();
|
||||
|
||||
|
||||
module test_coplanar() {
|
||||
assert(coplanar([ [5,5,1],[0,0,1],[-1,-1,1] ]) == false);
|
||||
assert(coplanar([ [5,5,1],[0,0,0],[-1,-1,1] ]) == true);
|
||||
assert(coplanar([ [0,0,0],[1,0,1],[1,1,1], [0,1,2] ]) == false);
|
||||
assert(coplanar([ [0,0,0],[1,0,1],[1,1,2], [0,1,1] ]) == true);
|
||||
module test_is_coplanar() {
|
||||
assert(is_coplanar([ [5,5,1],[0,0,1],[-1,-1,1] ]) == false);
|
||||
assert(is_coplanar([ [5,5,1],[0,0,0],[-1,-1,1] ]) == true);
|
||||
assert(is_coplanar([ [0,0,0],[1,0,1],[1,1,1], [0,1,2] ]) == false);
|
||||
assert(is_coplanar([ [0,0,0],[1,0,1],[1,1,2], [0,1,1] ]) == true);
|
||||
}
|
||||
*test_coplanar();
|
||||
*test_is_coplanar();
|
||||
|
||||
|
||||
module test_above_plane() {
|
||||
module test_is_above_plane() {
|
||||
plane = plane3pt([0,0,0], [0,10,10], [10,0,10]);
|
||||
assert(above_plane(plane, [5,5,10]) == false);
|
||||
assert(above_plane(plane, [-5,0,0]) == true);
|
||||
assert(above_plane(plane, [5,0,0]) == false);
|
||||
assert(above_plane(plane, [0,-5,0]) == true);
|
||||
assert(above_plane(plane, [0,5,0]) == false);
|
||||
assert(above_plane(plane, [0,0,5]) == true);
|
||||
assert(above_plane(plane, [0,0,-5]) == false);
|
||||
assert(is_above_plane(plane, [5,5,10]) == false);
|
||||
assert(is_above_plane(plane, [-5,0,0]) == true);
|
||||
assert(is_above_plane(plane, [5,0,0]) == false);
|
||||
assert(is_above_plane(plane, [0,-5,0]) == true);
|
||||
assert(is_above_plane(plane, [0,5,0]) == false);
|
||||
assert(is_above_plane(plane, [0,0,5]) == true);
|
||||
assert(is_above_plane(plane, [0,0,-5]) == false);
|
||||
}
|
||||
*test_above_plane();
|
||||
*test_is_above_plane();
|
||||
|
||||
|
||||
module test_is_path() {
|
||||
|
@ -820,15 +819,6 @@ module test_polygon_shift() {
|
|||
*test_polygon_shift();
|
||||
|
||||
|
||||
module test_polygon_shift_to_closest_point() {
|
||||
path = [[1,1],[-1,1],[-1,-1],[1,-1]];
|
||||
assert(polygon_shift_to_closest_point(path,[1.1,1.1]) == [[1,1],[-1,1],[-1,-1],[1,-1]]);
|
||||
assert(polygon_shift_to_closest_point(path,[-1.1,1.1]) == [[-1,1],[-1,-1],[1,-1],[1,1]]);
|
||||
assert(polygon_shift_to_closest_point(path,[-1.1,-1.1]) == [[-1,-1],[1,-1],[1,1],[-1,1]]);
|
||||
assert(polygon_shift_to_closest_point(path,[1.1,-1.1]) == [[1,-1],[1,1],[-1,1],[-1,-1]]);
|
||||
}
|
||||
*test_polygon_shift_to_closest_point();
|
||||
|
||||
|
||||
module test_reindex_polygon() {
|
||||
pent = subdivide_path([for(i=[0:4])[sin(72*i),cos(72*i)]],5);
|
||||
|
|
2
vnf.scad
2
vnf.scad
|
@ -1206,7 +1206,7 @@ function vnf_validate(vnf, show_warns=true, check_isects=false) =
|
|||
faceverts = [for (k=face) varr[k]]
|
||||
)
|
||||
if (is_num(area) && abs(area) > EPSILON)
|
||||
if (!coplanar(faceverts))
|
||||
if (!is_coplanar(faceverts))
|
||||
_vnf_validate_err("NONPLANAR", faceverts)
|
||||
]),
|
||||
issues = concat(issues, nonplanars)
|
||||
|
|
Loading…
Reference in a new issue