in commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/AbstractConvexPolygon3D.java [296:382]
public Split<PlaneConvexSubset> split(final Hyperplane<Vector3D> splitter) {
final Plane splitterPlane = (Plane) splitter;
final List<Vector3D> vertices = getVertices();
final int size = vertices.size();
int minusPlusTransitionIdx = -1;
Vector3D minusPlusInsertVertex = null;
int plusMinusTransitionIdx = -1;
Vector3D plusMinusInsertVertex = null;
int transitionCount = 0;
Vector3D curVertex;
HyperplaneLocation curLoc;
int lastSideIdx = -1;
Vector3D lastSideVertex = null;
HyperplaneLocation lastSideLoc = null;
int lastBoundaryIdx = -1;
for (int i = 0; i <= size || transitionCount == 1; ++i) {
curVertex = vertices.get(i % size);
curLoc = splitter.classify(curVertex);
if (lastSideLoc == HyperplaneLocation.MINUS && curLoc == HyperplaneLocation.PLUS) {
// transitioned from minus side to plus side
minusPlusTransitionIdx = Math.max(lastSideIdx, lastBoundaryIdx);
++transitionCount;
if (lastBoundaryIdx < 0) {
// no shared boundary point; compute a new vertex
minusPlusInsertVertex = splitterPlane.intersection(
Lines3D.fromPoints(lastSideVertex, curVertex, splitterPlane.getPrecision()));
}
} else if (lastSideLoc == HyperplaneLocation.PLUS && curLoc == HyperplaneLocation.MINUS) {
// transitioned from plus side to minus side
plusMinusTransitionIdx = Math.max(lastSideIdx, lastBoundaryIdx);
++transitionCount;
if (lastBoundaryIdx < 0) {
// no shared boundary point; compute a new vertex
plusMinusInsertVertex = splitterPlane.intersection(
Lines3D.fromPoints(lastSideVertex, curVertex, splitterPlane.getPrecision()));
}
}
if (curLoc == HyperplaneLocation.ON) {
lastBoundaryIdx = i;
} else {
lastBoundaryIdx = -1;
lastSideIdx = i;
lastSideVertex = curVertex;
lastSideLoc = curLoc;
}
}
if (minusPlusTransitionIdx > -1 && plusMinusTransitionIdx > -1) {
// we've split; compute the vertex list for each side
final List<Vector3D> minusVertices = buildPolygonSplitVertexList(
plusMinusTransitionIdx, plusMinusInsertVertex,
minusPlusTransitionIdx, minusPlusInsertVertex, vertices);
final List<Vector3D> plusVertices = buildPolygonSplitVertexList(
minusPlusTransitionIdx, minusPlusInsertVertex,
plusMinusTransitionIdx, plusMinusInsertVertex, vertices);
// delegate back to the Planes factory methods to determine the concrete types
// for each side of the split
return new Split<>(
Planes.fromConvexPlanarVertices(plane, minusVertices),
Planes.fromConvexPlanarVertices(plane, plusVertices));
} else if (lastSideLoc == HyperplaneLocation.PLUS) {
// we lie entirely on the plus side of the splitter
return new Split<>(null, this);
} else if (lastSideLoc == HyperplaneLocation.MINUS) {
// we lie entirely on the minus side of the splitter
return new Split<>(this, null);
}
// we lie entirely on the splitter
return new Split<>(null, null);
}