in commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/ConvexVolume.java [79:118]
public Vector3D getCentroid() {
double volumeSum = 0.0;
double sumX = 0.0;
double sumY = 0.0;
double sumZ = 0.0;
for (final PlaneConvexSubset boundary : getBoundaries()) {
if (boundary.isInfinite()) {
return null;
}
final Plane boundaryPlane = boundary.getPlane();
final double boundaryArea = boundary.getSize();
final Vector3D boundaryCentroid = boundary.getCentroid();
final double scaledVolume = boundaryArea * boundaryCentroid.dot(boundaryPlane.getNormal());
volumeSum += scaledVolume;
sumX += scaledVolume * boundaryCentroid.getX();
sumY += scaledVolume * boundaryCentroid.getY();
sumZ += scaledVolume * boundaryCentroid.getZ();
}
if (volumeSum > 0) {
final double size = volumeSum / 3.0;
// Since the volume we used when adding together the boundary contributions
// was 3x the actual pyramid size, we'll multiply by 1/4 here instead
// of 3/4 to adjust for the actual centroid position in each pyramid.
final double centroidScale = 1.0 / (4 * size);
return Vector3D.of(
sumX * centroidScale,
sumY * centroidScale,
sumZ * centroidScale);
}
return null;
}