in commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/ConvexArea.java [221:271]
public static ConvexArea convexPolygonFromPath(final LinePath path) {
// ensure that the path is closed; this also ensures that we do not have any infinite elements
if (!path.isClosed()) {
throw new IllegalArgumentException("Cannot construct convex polygon from unclosed path: " + path);
}
final List<LineConvexSubset> elements = path.getElements();
if (elements.size() < 3) {
throw new IllegalArgumentException(
"Cannot construct convex polygon from path with less than 3 elements: " + path);
}
// go through the elements and validate that the produced area is convex and finite
// using the precision context from the first path element
final LineConvexSubset startElement = elements.get(0);
final Vector2D startVertex = startElement.getStartPoint();
final Precision.DoubleEquivalence precision = startElement.getPrecision();
Vector2D curVector;
Vector2D prevVector = null;
double signedArea;
double totalSignedArea = 0.0;
LineConvexSubset element;
// we can skip the last element since the we know that the path is closed, meaning that the
// last element's end point is equal to our start point
for (int i = 0; i < elements.size() - 1; ++i) {
element = elements.get(i);
curVector = startVertex.vectorTo(element.getEndPoint());
if (prevVector != null) {
signedArea = prevVector.signedArea(curVector);
if (precision.lt(signedArea, 0.0)) {
throw new IllegalArgumentException(NON_CONVEX_PATH_ERROR + path);
}
totalSignedArea += signedArea;
}
prevVector = curVector;
}
if (precision.lte(totalSignedArea, 0.0)) {
throw new IllegalArgumentException(NON_CONVEX_PATH_ERROR + path);
}
return new ConvexArea(elements);
}