Review of vnf_centroid()

This commit is contained in:
RonaldoCMP 2021-04-11 12:36:05 +01:00
parent 376609d52f
commit c5799d6539
2 changed files with 8 additions and 11 deletions

View file

@ -74,7 +74,8 @@ module test_vnf_centroid() {
assert_approx(vnf_centroid(cube(100, anchor=TOP)), [0,0,-50]);
assert_approx(vnf_centroid(sphere(d=100, anchor=CENTER, $fn=36)), [0,0,0]);
assert_approx(vnf_centroid(sphere(d=100, anchor=BOT, $fn=36)), [0,0,50]);
}
ellipse = xscale(2, p=circle($fn=24, r=3));
assert_approx(vnf_centroid(path_sweep(pentagon(r=1), path3d(ellipse), closed=true)),[0,0,0]);}
test_vnf_centroid();

View file

@ -450,18 +450,13 @@ function vnf_volume(vnf) =
// Returns the centroid of the given manifold VNF. The VNF must describe a valid polyhedron with consistent face direction and
// no holes; otherwise the results are undefined.
// Divide the solid up into tetrahedra with the origin as one vertex. The centroid of a tetrahedron is the average of its vertices.
// Divide the solid up into tetrahedra with the origin as one vertex.
// The centroid of a tetrahedron is the average of its vertices.
// The centroid of the total is the volume weighted average.
function vnf_centroid(vnf) =
assert(is_vnf(vnf) && len(vnf[0])!=0 )
let(
verts = vnf[0],
vol = sum([
for(face=vnf[1], j=[1:1:len(face)-2]) let(
v0 = verts[face[0]],
v1 = verts[face[j]],
v2 = verts[face[j+1]]
) cross(v2,v1)*v0
]),
pos = sum([
for(face=vnf[1], j=[1:1:len(face)-2]) let(
v0 = verts[face[0]],
@ -469,10 +464,11 @@ function vnf_centroid(vnf) =
v2 = verts[face[j+1]],
vol = cross(v2,v1)*v0
)
(v0+v1+v2)*vol
[ vol, (v0+v1+v2)*vol ]
])
)
pos/vol/4;
assert(!approx(pos[0],0, EPSILON), "The vnf has self-intersections.")
pos[1]/pos[0]/4;
function _triangulate_planar_convex_polygons(polys) =