in commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/RegionBSPTree2D.java [202:258]
protected RegionSizeProperties<Vector2D> computeRegionSizeProperties() {
// handle simple cases
if (isFull()) {
return new RegionSizeProperties<>(Double.POSITIVE_INFINITY, null);
} else if (isEmpty()) {
return new RegionSizeProperties<>(0, null);
}
// compute the size based on the boundary line subsets
double quadrilateralAreaSum = 0.0;
double scaledSumX = 0.0;
double scaledSumY = 0.0;
Vector2D startPoint;
Vector2D endPoint;
double signedArea;
for (final LineConvexSubset boundary : boundaries()) {
if (boundary.isInfinite()) {
// at least on boundary is infinite, meaning that
// the size is also infinite
quadrilateralAreaSum = Double.POSITIVE_INFINITY;
break;
}
startPoint = boundary.getStartPoint();
endPoint = boundary.getEndPoint();
// compute the area
signedArea = startPoint.signedArea(endPoint);
quadrilateralAreaSum += signedArea;
// compute scaled coordinate values for the centroid
scaledSumX += signedArea * (startPoint.getX() + endPoint.getX());
scaledSumY += signedArea * (startPoint.getY() + endPoint.getY());
}
double size = Double.POSITIVE_INFINITY;
Vector2D centroid = null;
// The area is finite only if the computed quadrilateral area is finite and non-negative.
// Negative areas indicate that the region is inside-out, with a finite outside surrounded
// by an infinite inside.
if (quadrilateralAreaSum >= 0 && Double.isFinite(quadrilateralAreaSum)) {
size = 0.5 * quadrilateralAreaSum;
if (quadrilateralAreaSum > 0) {
centroid = Vector2D.of(scaledSumX, scaledSumY).multiply(1.0 / (3.0 * quadrilateralAreaSum));
}
}
return new RegionSizeProperties<>(size, centroid);
}