diff --git a/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs b/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs index 9211fa15b..fcf1ee364 100644 --- a/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs +++ b/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs @@ -319,13 +319,30 @@ internal static partial class ElkEdgeRouterIterative var src = cpath[0]; var tgt = cpath[^1]; var stubX = src.X + 24d; + var tgtNode = nodesById.TryGetValue(edge.TargetNodeId ?? string.Empty, out var tn) ? tn : null; // Large vertical separation (2x nodeSizeClearance) between - // corridors so they're visually distinct. Simple vertical - // drop to target — no right-side wrapping that congests - // the area near the End node. + // corridors so they're visually distinct. var localCorridorY = baseCorridorY - (corridorFixed * (nodeSizeClearance * 2d)); List newPath; + if (tgtNode is not null) + { + // Drop to left of target, then approach from the left face. + // All End-targeting edges enter from the same direction for + // a clean fan-in instead of a 3-face tangle. + var dropX = tgtNode.X - 24d - (corridorFixed * (nodeSizeClearance * 2d)); + var entryY = tgtNode.Y + (tgtNode.Height * (0.33d + corridorFixed * 0.34d)); + newPath = + [ + src, + new() { X = stubX, Y = src.Y }, + new() { X = stubX, Y = localCorridorY }, + new() { X = dropX, Y = localCorridorY }, + new() { X = dropX, Y = entryY }, + new() { X = tgtNode.X, Y = entryY }, + ]; + } + else { newPath = [