protected int doChooseSplitIndex(List<DBTreeRecord<?, ? extends NS>> children,
			Comparator<NS> axis) {
		children.sort(Comparator.comparing(DBTreeRecord::getBounds, axis));

		// Distributions as described in Section 4.2
		// Precompute the bounding boxes of each pair, incrementally.
		// ************X (M = 12)
		// mmm-------mmm (m = 3)
		// 8 distributions : 12 - 2*3 + 2

		NS boundsFirstKChildren =
			unionStream(children.subList(0, minChildren).stream().map(DBTreeRecord::getBounds));
		NS boundsLastKChildren =
			unionStream(children.subList(maxChildren + 1 - minChildren, maxChildren + 1)
					.stream()
					.map(DBTreeRecord::getBounds));
		int maxK = maxChildren + 1 - minChildren * 2;

		Deque<NS> boundsFirsts = new ArrayDeque<>();
		Deque<NS> boundsSeconds = new ArrayDeque<>();
		boundsFirsts.addLast(boundsFirstKChildren);
		boundsSeconds.addFirst(boundsLastKChildren);
		for (int k = 0; k <= maxK; k++) {
			NS forFirst = children.get(minChildren + k).getBounds();
			NS forSecond = children.get(maxChildren - minChildren - k).getBounds();

			boundsFirstKChildren = boundsFirstKChildren.unionBounds(forFirst);
			boundsLastKChildren = boundsLastKChildren.unionBounds(forSecond);

			boundsFirsts.addLast(boundsFirstKChildren);
			boundsSeconds.addFirst(boundsLastKChildren);
		}

		// CSI1
		double bestOverlapValue = Double.MAX_VALUE;
		double bestAreaValue = Double.MAX_VALUE;
		int bestIndex = -1;
		for (int k = 0; k <= maxK; k++) {
			NS boundsFirstGroup = boundsFirsts.removeFirst();
			NS boundsSecondGroup = boundsSeconds.removeFirst();
			double overlapValue = boundsFirstGroup.computeAreaIntersection(boundsSecondGroup);
			double areaValue = boundsFirstGroup.getArea() + boundsSecondGroup.getArea();
			if (bestIndex == -1 || overlapValue < bestOverlapValue ||
				(overlapValue == bestOverlapValue && areaValue < bestAreaValue)) {
				bestIndex = k;
				bestOverlapValue = overlapValue;
			}
		}
		assert bestIndex != -1;
		return bestIndex + minChildren;
	}
The Split algorithm as defined in Section 4.2 of the paper.

@param n the node to split
@return the new node (containing the second group)
Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/spatial/AbstractRStarConstraintsTree.java