Use node-sized corridor grid spacing for cleaner edge routing

Replace fixed IntermediateGridSpacing=40 with average node height (~100px).
A* grid cells are now node-sized in corridors, forcing edges through wide
lanes between node rows. Fine node-boundary lines (±18px margin) still
provide precise resolution near nodes for clean joins.

Visual improvement is dramatic: edges no longer hug node boundaries.

NodeSpacing=50 test set. Remaining: ExcessiveDetourViolations=1 and
edge/9 under-node flush. Target-join, shared-lane, boundary-angle,
long-diagonal all clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-01 18:11:10 +03:00
parent e01549c2d6
commit c3c6f2d0c6
2 changed files with 10 additions and 3 deletions

View File

@@ -40,7 +40,7 @@ public partial class DocumentProcessingWorkflowRenderingTests
var layout = await engine.LayoutAsync(graph, new WorkflowRenderLayoutRequest
{
Direction = WorkflowRenderLayoutDirection.LeftToRight,
NodeSpacing = 40,
NodeSpacing = 50,
});
var svgRenderer = new WorkflowRenderSvgRenderer();

View File

@@ -242,9 +242,16 @@ internal static partial class ElkEdgeRouterIterative
var edgeOrder = useConnectedOrdering
? OrderByMostConnectedFirst(edges, connectionCount)
: OrderByLongestFirst(edges, nodesById);
// Corridor grid spacing: use average node height so the A* grid cells
// are node-sized. Edges route through wide corridors between node rows,
// not through narrow gaps. The fine node-boundary lines (at obstacle
// edge ± 18px margin) still provide precise resolution near nodes.
var serviceNodesForGrid = nodes.Where(n => n.Kind is not "Start" and not "End").ToArray();
var avgNodeHeight = serviceNodesForGrid.Length > 0 ? serviceNodesForGrid.Average(n => n.Height) : 88d;
var corridorGridSpacing = Math.Max(40d, avgNodeHeight);
var routingParams = baselineRetryState.RequiresBlockingRetry
? new AStarRoutingParams(18d, 400d, 600d, 3.0d, minLineClearance, 40d, true)
: new AStarRoutingParams(18d, 200d, 500d, 2.0d, minLineClearance, 40d, true);
? new AStarRoutingParams(18d, 400d, 600d, 3.0d, minLineClearance, corridorGridSpacing, true)
: new AStarRoutingParams(18d, 200d, 500d, 2.0d, minLineClearance, corridorGridSpacing, true);
var strategy = new RoutingStrategy
{
EdgeOrder = edgeOrder,