Reroute long horizontal sweeps through top corridor

Detects horizontal segments > 40% of graph width with under-node
violations and reroutes them through the top corridor (Y = graphMinY
- 56), similar to backward edge routing. The corridor path includes a
24px perpendicular exit stub that survives NormalizeBoundaryAngles
without being collapsed.

Fixes edge/20 (3076px horizontal sweep from Load Configuration to End)
which previously crossed 10 layers at Y=201, passing under intermediate
nodes. Now routes above the graph at Y=-24.

Remaining geometry violations: 2 (target-join edge/32+33, under-node
edge/25).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-30 09:34:04 +03:00
parent 7e62f9c0c4
commit 77bb608325
2 changed files with 154 additions and 0 deletions

View File

@@ -88,6 +88,34 @@ internal static partial class ElkEdgeRouterIterative
}
}
// Reroute long horizontal sweeps through the top corridor.
// Edges spanning > half the graph width with under-node violations
// should route above the graph (like backward edges) instead of
// cutting straight through the node field.
if (current.RetryState.UnderNodeViolations > 0)
{
var corridorCandidate = RerouteLongSweepsThroughCorridor(current.Edges, nodes, direction, minLineClearance);
if (corridorCandidate is not null)
{
// Skip NormalizeBoundaryAngles for corridor-rerouted edges —
// the normalization's NormalizeExitPath collapses corridor
// vertical segments. The corridor path already has a correct
// perpendicular exit stub.
var corridorScore = ElkEdgeRoutingScoring.ComputeScore(corridorCandidate, nodes);
if (corridorScore.Value > current.Score.Value
&& corridorScore.NodeCrossings <= current.Score.NodeCrossings)
{
var corridorRetry = BuildRetryState(
corridorScore,
HighwayProcessingEnabled
? ElkEdgeRouterHighway.DetectRemainingBrokenHighways(corridorCandidate, nodes).Count
: 0);
current = current with { Score = corridorScore, RetryState = corridorRetry, Edges = corridorCandidate };
ElkLayoutDiagnostics.LogProgress($"Hybrid winner refinement after corridor reroute: {DescribeSolution(current)}");
}
}
}
// Targeted under-node elevation with net-total promotion.
// ElevateUnderNodeViolations can fix remaining under-node edges
// (gateway-exit lanes, long horizontal sweeps) but the standard