Added pointslist_is_coplanar(). Added coplanar check to plane_from_pointslist().

This commit is contained in:
Revar Desmera 2020-03-13 18:45:46 -07:00
parent 4b5e0835cc
commit efa75eaf5a
2 changed files with 33 additions and 7 deletions

View file

@ -624,19 +624,29 @@ function plane_from_normal(normal, pt) =
// Function: plane_from_pointslist() // Function: plane_from_pointslist()
// Usage: // Usage:
// plane_from_pointslist(points); // plane_from_pointslist(points, [fast], [eps]);
// Description: // Description:
// Given a list of 3 or more coplanar points, returns the cartesian equation of a plane. // Given a list of 3 or more coplanar points, returns the cartesian equation of a plane.
// Returns [A,B,C,D] where Ax+By+Cz=D is the equation of the plane. // Returns [A,B,C,D] where Ax+By+Cz=D is the equation of the plane.
function plane_from_pointslist(points) = // If not all the points in the points list are coplanar, then `undef` is returned.
// If `fast` is true, then a list where not all points are coplanar will result
// in an invalid plane value, as all coplanar checks are skipped.
// Arguments:
// points = The list of points to find the plane of.
// fast = If true, don't verify that all points in the list are coplanar. Default: false
// eps = How much variance is allowed in testing that each point is on the same plane. Default: `EPSILON` (1e-9)
function plane_from_pointslist(points, fast=false, eps=EPSILON) =
let( let(
points = deduplicate(points), points = deduplicate(points),
indices = sort(find_noncollinear_points(points)), indices = sort(find_noncollinear_points(points)),
p1 = points[indices[0]], p1 = points[indices[0]],
p2 = points[indices[1]], p2 = points[indices[1]],
p3 = points[indices[2]], p3 = points[indices[2]],
plane = plane3pt(p1,p2,p3) plane = plane3pt(p1,p2,p3),
) plane; all_coplanar = fast || all([
for (pt = points) coplanar(plane,pt,eps=eps)
])
) all_coplanar? plane : undef;
// Function: plane_normal() // Function: plane_normal()
@ -779,8 +789,24 @@ function polygon_line_intersection(poly, line, bounded=false, eps=EPSILON) =
// Arguments: // Arguments:
// plane = The [A,B,C,D] values for the equation of the plane. // plane = The [A,B,C,D] values for the equation of the plane.
// point = The point to test. // point = The point to test.
function coplanar(plane, point) = // eps = How much variance is allowed in testing that each point is on the same plane. Default: `EPSILON` (1e-9)
abs(distance_from_plane(plane, point)) <= EPSILON; function coplanar(plane, point, eps=EPSILON) =
abs(distance_from_plane(plane, point)) <= eps;
// Function: pointslist_is_coplanar()
// Usage:
// pointslist_is_coplanar(points);
// Description:
// Given a list of points, returns true if all points in the list are coplanar.
// Arguments:
// points = The list of points to test.
// eps = How much variance is allowed in testing that each point is on the same plane. Default: `EPSILON` (1e-9)
function pointslist_is_coplanar(points, eps=EPSILON) =
let(
plane = plane_from_pointslist(points, fast=true, eps=eps)
) all([for (pt = points) coplanar(plane, pt, eps=eps)]);
// Function: in_front_of_plane() // Function: in_front_of_plane()

View file

@ -8,7 +8,7 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
BOSL_VERSION = [2,0,183]; BOSL_VERSION = [2,0,184];
// Section: BOSL Library Version Functions // Section: BOSL Library Version Functions