darkma773r commented on a change in pull request #97:
URL: https://github.com/apache/commons-geometry/pull/97#discussion_r454072077
##########
File path:
commons-geometry-spherical/src/main/java/org/apache/commons/geometry/spherical/twod/ConvexArea2S.java
##########
@@ -132,35 +139,167 @@ public Point2S getCentroid() {
return weighted == null ? null : Point2S.from(weighted);
}
- /** Returns the weighted vector for the centroid. This vector is computed
by scaling the
- * pole vector of the great circle of each boundary arc by the size of the
arc and summing
- * the results. By combining the weighted centroid vectors of multiple
areas, a single
- * centroid can be computed for the whole group.
+ /** Return the weighted centroid vector of the area. The returned vector
points in the direction of the
+ * centroid point on the surface of the unit sphere with the length of the
vector proportional to the
+ * effective mass of the area at the centroid. By adding the weighted
centroid vectors of multiple
+ * convex areas, a single centroid can be computed for the combined area.
* @return weighted centroid vector.
* @see <a href="https://archive.org/details/centroidinertiat00broc">
* <em>The Centroid and Inertia Tensor for a Spherical Triangle</em> -
John E. Brock</a>
*/
Vector3D getWeightedCentroidVector() {
final List<GreatArc> arcs = getBoundaries();
- switch (arcs.size()) {
+ final int numBoundaries = arcs.size();
+
+ switch (numBoundaries) {
case 0:
// full space; no centroid
return null;
case 1:
- // hemisphere; centroid is the pole of the hemisphere
- final GreatArc singleArc = arcs.get(0);
- return
singleArc.getCircle().getPole().withNorm(singleArc.getSize());
+ // hemisphere
+ return computeHemisphereWeightedCentroidVector(arcs.get(0));
+ case 2:
+ // lune
+ return computeLuneWeightedCentroidVector(arcs.get(0), arcs.get(1));
default:
- // 2 or more sides; use an extension of the approach outlined here:
- // https://archive.org/details/centroidinertiat00broc
- // In short, the centroid is the sum of the pole vectors of each
side
- // multiplied by their arc lengths.
- Vector3D centroid = Vector3D.ZERO;
- for (final GreatArc arc : getBoundaries()) {
- centroid =
centroid.add(arc.getCircle().getPole().withNorm(arc.getSize()));
+ // triangle or other convex polygon
+ final double arcLengthSum = arcs.stream()
+ .mapToDouble(GreatArc::getSize)
+ .sum();
+
+ if (arcLengthSum < TRIANGLE_FAN_CENTROID_COMPUTE_THRESHOLD) {
+ return computeTriangleFanWeightedCentroidVector(arcs);
+ }
+
+ return computeArcPoleWeightedCentroidVector(arcs);
+ }
+ }
+
+ /** Compute the weighted centroid vector for the hemisphere formed by the
given arc.
+ * @param arc arc defining the hemisphere
+ * @return the weighted centroid vector for the hemisphere
+ * @see #getWeightedCentroidVector()
+ */
+ private Vector3D computeHemisphereWeightedCentroidVector(final GreatArc
arc) {
Review comment:
Sounds good.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]