protected RegionSizeProperties computeRegionSizeProperties()

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);
    }