private int findRoutingColumn(E e, GridPoint p1, GridPoint p2) {
		if (p2.row == p1.row + 2) {
			return p1.col;			// direct child 
		}
		int startRow = Math.min(p1.row + 1, p2.row - 1);
		int endRow = Math.max(p1.row + 1, p2.row - 1);
		int startCol = Math.min(p1.col, p2.col);
		int endCol = Math.max(p1.col, p2.col);
		boolean isBackEdge = p2.row <= p1.row;

		// If not a back edge, try to route in between start and end columns, but we decided not
		// to ever route back edges in between so that back edges have C-shape or backwards C-shape
		// and not a Z-shape.
		if (!isBackEdge) {
			// try if either start or end column is open
			if (isOpenPath(p1.col, startRow, endRow)) {
				return p1.col;
			}
			if (isOpenPath(p2.col, startRow, endRow)) {
				return p2.col;
			}

			for (int col = startCol + 1; col <= endCol - 1; col++) {
				if (isOpenPath(col, startRow, endRow)) {
					return col;
				}
			}
		}

		// Get an optional excluded range where we don't want to route a specific edge. By
		// default the range is empty, allowing any column.
		GridRange excludedRange = excludedColumnsFunction.apply(e);

		// try each left and right column expanding outwards, starting at the columns of
		// the start and end vertex.
		for (int i = 1; i <= startCol; i++) {
			int left = startCol - i;
			int right = endCol + i;

			boolean leftExcluded = excludedRange.contains(left);
			boolean rightExcluded = excludedRange.contains(right);
			boolean leftValid = !leftExcluded && isOpenPath(left, startRow, endRow);
			boolean rightValid = !rightExcluded && isOpenPath(right, startRow, endRow);
			if (leftValid) {
				if (!rightValid) {
					return left;
				}
				// if both are open, prefer left for forward edges, right for back edges
				return p1.row < p2.row ? left : right;
			}
			else if (rightValid) {
				return right;
			}
		}
		return 0;	// 0 is always open as we avoid putting vertices in the 0 column
	}
Sets a function that can be used to prevent edges from being routed in  a range of columns.
One use of this is to prevent back edges from intersecting any child trees in its ancestor
hierarchy between the start vertex and the end vertex.  
@param excludedColumnsFunction the function to call to compute a range of columns to 
prevent routing edges.
Ghidra/Features/FunctionGraph/src/main/java/ghidra/app/plugin/core/functiongraph/graph/layout/flowchart/OrthogonalEdgeRouter.java