in commons-geometry-spherical/src/main/java/org/apache/commons/geometry/spherical/twod/RegionBSPTree2S.java [162:204]
protected RegionSizeProperties<Point2S> computeRegionSizeProperties() {
// handle simple cases
if (isFull()) {
return new RegionSizeProperties<>(FULL_SIZE, null);
} else if (isEmpty()) {
return new RegionSizeProperties<>(0, null);
}
final List<ConvexArea2S> areas = toConvex();
final Precision.DoubleEquivalence precision = ((GreatArc) getRoot().getCut()).getPrecision();
final Sum sizeSum = Sum.create();
final Vector3D.Sum centroidVectorSum = Vector3D.Sum.create();
double maxCentroidVectorWeightSq = 0.0;
for (final ConvexArea2S area : areas) {
sizeSum.add(area.getSize());
final Vector3D areaCentroidVector = area.getWeightedCentroidVector();
maxCentroidVectorWeightSq = Math.max(maxCentroidVectorWeightSq, areaCentroidVector.normSq());
centroidVectorSum.add(areaCentroidVector);
}
final double size = sizeSum.getAsDouble();
final Vector3D centroidVector = centroidVectorSum.get();
// Convert the weighted centroid vector to a point on the sphere surface. If the centroid vector
// length is less than the max length of the combined convex areas and the vector itself is
// equivalent to zero, then we know that there are opposing and approximately equal areas in the
// region, resulting in an indeterminate centroid. This would occur, for example, if there were
// equal areas around each pole.
final Point2S centroid;
if (centroidVector.normSq() < maxCentroidVectorWeightSq &&
centroidVector.eq(Vector3D.ZERO, precision)) {
centroid = null;
} else {
centroid = Point2S.from(centroidVector);
}
return new RegionSizeProperties<>(size, centroid);
}