Improved centroid() to work with 3D planar polygons.

This commit is contained in:
Revar Desmera 2019-12-05 14:01:40 -08:00
parent f0915b8e0b
commit 24de174d6f
2 changed files with 21 additions and 9 deletions

View file

@ -1090,16 +1090,28 @@ function find_noncollinear_points(points) =
// Function: centroid() // Function: centroid()
// Usage: // Usage:
// centroid(vertices) // cp = centroid(poly);
// Description: // Description:
// Given a simple 2D polygon, returns the coordinates of the polygon's centroid. // Given a simple 2D polygon, returns the 2D coordinates of the polygon's centroid.
// Given a simple 3D planar polygon, returns the 3D coordinates of the polygon's centroid.
// If the polygon is self-intersecting, the results are undefined. // If the polygon is self-intersecting, the results are undefined.
function centroid(vertices) = function centroid(poly) =
sum([ len(poly[0])==2? (
for(i=[0:len(vertices)-1]) sum([
let(segment=select(vertices,i,i+1)) for(i=[0:len(poly)-1])
det2(segment)*sum(segment) let(segment=select(poly,i,i+1))
]) / 6 / polygon_area(vertices); det2(segment)*sum(segment)
]) / 6 / polygon_area(poly)
) : (
let(
n = plane_normal(plane_from_pointslist(poly)),
p1 = vector_angle(n,UP)>15? vector_axis(n,UP) : vector_axis(n,RIGHT),
p2 = vector_axis(n,p1),
cp = mean(poly),
proj = project_plane(poly,cp,cp+p1,cp+p2),
cxy = centroid(proj)
) lift_plane(cxy,cp,cp+p1,cp+p2)
);
// Function: simplify_path() // Function: simplify_path()

View file

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