in commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTree.java [719:790]
private N splitInternalNode(final N node, final HyperplaneConvexSubset<P> partitioner) {
// split the partitioner and node cut with each other's hyperplanes to determine their relative positions
final Split<? extends HyperplaneConvexSubset<P>> partitionerSplit = partitioner.split(node.getCutHyperplane());
final Split<? extends HyperplaneConvexSubset<P>> nodeCutSplit =
node.getCut().split(partitioner.getHyperplane());
final SplitLocation partitionerSplitSide = partitionerSplit.getLocation();
final SplitLocation nodeCutSplitSide = nodeCutSplit.getLocation();
final N result = createNode();
final N resultMinus;
final N resultPlus;
if (partitionerSplitSide == SplitLocation.PLUS) {
if (nodeCutSplitSide == SplitLocation.PLUS) {
// partitioner is on node cut plus side, node cut is on partitioner plus side
final N nodePlusSplit = splitSubtree(node.getPlus(), partitioner);
resultMinus = nodePlusSplit.getMinus();
resultPlus = copyNode(node);
resultPlus.setSubtree(node.getCut(), importSubtree(node.getMinus()), nodePlusSplit.getPlus());
} else {
// partitioner is on node cut plus side, node cut is on partitioner minus side
final N nodePlusSplit = splitSubtree(node.getPlus(), partitioner);
resultMinus = copyNode(node);
resultMinus.setSubtree(node.getCut(), importSubtree(node.getMinus()), nodePlusSplit.getMinus());
resultPlus = nodePlusSplit.getPlus();
}
} else if (partitionerSplitSide == SplitLocation.MINUS) {
if (nodeCutSplitSide == SplitLocation.MINUS) {
// partitioner is on node cut minus side, node cut is on partitioner minus side
final N nodeMinusSplit = splitSubtree(node.getMinus(), partitioner);
resultMinus = copyNode(node);
resultMinus.setSubtree(node.getCut(), nodeMinusSplit.getMinus(), importSubtree(node.getPlus()));
resultPlus = nodeMinusSplit.getPlus();
} else {
// partitioner is on node cut minus side, node cut is on partitioner plus side
final N nodeMinusSplit = splitSubtree(node.getMinus(), partitioner);
resultMinus = nodeMinusSplit.getMinus();
resultPlus = copyNode(node);
resultPlus.setSubtree(node.getCut(), nodeMinusSplit.getPlus(), importSubtree(node.getPlus()));
}
} else if (partitionerSplitSide == SplitLocation.BOTH) {
// partitioner and node cut split each other
final N nodeMinusSplit = splitSubtree(node.getMinus(), partitionerSplit.getMinus());
final N nodePlusSplit = splitSubtree(node.getPlus(), partitionerSplit.getPlus());
resultMinus = copyNode(node);
resultMinus.setSubtree(nodeCutSplit.getMinus(), nodeMinusSplit.getMinus(), nodePlusSplit.getMinus());
resultPlus = copyNode(node);
resultPlus.setSubtree(nodeCutSplit.getPlus(), nodeMinusSplit.getPlus(), nodePlusSplit.getPlus());
} else {
// partitioner and node cut are parallel or anti-parallel
final boolean sameOrientation = partitioner.getHyperplane().similarOrientation(node.getCutHyperplane());
resultMinus = importSubtree(sameOrientation ? node.getMinus() : node.getPlus());
resultPlus = importSubtree(sameOrientation ? node.getPlus() : node.getMinus());
}
result.setSubtree(partitioner, resultMinus, resultPlus);
return result;
}