Visually distinct corridor highways with wide separation

Two corridor sweeps now separated by 2x nodeSizeClearance (~105px)
instead of nodeSizeClearance+4 (~57px). Each enters End at a distinct
right-face position (1/3 and 2/3 height). Corridors are clearly
traceable from source to terminus.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-02 10:18:10 +03:00
parent 7d0fea3149
commit 640ad058e5

View File

@@ -315,38 +315,31 @@ internal static partial class ElkEdgeRouterIterative
var segLen = Math.Abs(cpath[si + 1].X - cpath[si].X);
var laneY = cpath[si].Y;
if (segLen < localMinSweep || laneY <= graphMinYLocal - 10d) continue;
// Offset must exceed the target-join detection threshold
// (node-size clearance, not spacing-scaled) so parallel
// corridor segments aren't flagged as joins.
var nodeSizeClearance = ElkEdgeRoutingScoring.ResolveNodeSizeClearance(nodes);
var localCorridorY = baseCorridorY - (corridorFixed * (nodeSizeClearance + 4d));
var src = cpath[0];
var tgt = cpath[^1];
var stubX = src.X + 24d;
// Find the target node to determine approach geometry.
var tgtNode = nodesById.TryGetValue(edge.TargetNodeId ?? string.Empty, out var tn) ? tn : null;
// Both corridors go ABOVE the graph but with large vertical
// separation (2x nodeSizeClearance) so they're visually distinct.
var localCorridorY = baseCorridorY - (corridorFixed * (nodeSizeClearance * 2d));
List<ElkPoint> newPath;
if (tgtNode is not null && tgtNode.Kind is "End")
{
// Enter End from the right side: corridor goes past End,
// descends to End's center Y, approaches from right.
// This avoids the ugly long vertical drop from corridor.
// Offset both X and Y for each corridor edge so they
// enter End at distinct positions (visually traceable).
// Enter End from the right side at a distinct Y position.
var rightApproachX = tgtNode.X + tgtNode.Width + 24d + (corridorFixed * (nodeSizeClearance + 4d));
// Spread entry points across the right face. First edge
// enters at 1/3 from top, second at 2/3, etc.
var slotFraction = (corridorFixed + 1d) / (corridorFixed + 2d);
var centerY = tgtNode.Y + (tgtNode.Height * slotFraction);
var slotFraction = corridorFixed == 0 ? 0.33d : 0.67d;
var entryY = tgtNode.Y + (tgtNode.Height * slotFraction);
newPath =
[
src,
new() { X = stubX, Y = src.Y },
new() { X = stubX, Y = localCorridorY },
new() { X = rightApproachX, Y = localCorridorY },
new() { X = rightApproachX, Y = centerY },
new() { X = tgtNode.X + tgtNode.Width, Y = centerY },
new() { X = rightApproachX, Y = entryY },
new() { X = tgtNode.X + tgtNode.Width, Y = entryY },
];
}
else