Extend under-node detection for edges flush with node boundaries
Edges running alongside a node's top or bottom boundary (within 4px) are now flagged as under-node violations — they're visually "glued" to the node edge. Previously, only edges BELOW the node bottom were detected (gap > 0.5px). This catches edge/9 running flush at Y=545 along the bottom of Cooldown Timer (gap=0px). Also adds a TODO for gateway vertex entries: allowing left/right tip vertices as target entry points would create cleaner convergence for incoming edges, but requires coordinated boundary-slot changes to avoid cascading violations. The approach is validated but not yet safe to enable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,15 +94,21 @@ internal static partial class ElkEdgeRouterIterative
|
||||
|
||||
var nodeBottom = node.Y + node.Height;
|
||||
var gap = laneY - nodeBottom;
|
||||
if (gap > 0.5d && gap < minClearance)
|
||||
// Check both standard under-node (gap 0.5-minClearance)
|
||||
// and flush alongside (gap -4 to 0.5, touching boundary).
|
||||
var isUnder = gap > 0.5d && gap < minClearance;
|
||||
var isFlush = gap >= -4d && gap <= 0.5d;
|
||||
if (!isUnder && !isFlush)
|
||||
{
|
||||
var minX = Math.Min(path[i].X, path[i + 1].X);
|
||||
var maxX = Math.Max(path[i].X, path[i + 1].X);
|
||||
if (maxX > node.X - 0.5d && minX < node.X + node.Width + 0.5d)
|
||||
{
|
||||
hasGatewayExitUnderNode = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var minX = Math.Min(path[i].X, path[i + 1].X);
|
||||
var maxX = Math.Max(path[i].X, path[i + 1].X);
|
||||
if (maxX > node.X - 0.5d && minX < node.X + node.Width + 0.5d)
|
||||
{
|
||||
hasGatewayExitUnderNode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,8 +323,16 @@ internal static class ElkEdgeRoutingScoring
|
||||
continue;
|
||||
}
|
||||
|
||||
var distanceBelowNode = laneY - (node.Y + node.Height);
|
||||
if (distanceBelowNode <= 0.5d || distanceBelowNode >= minClearance)
|
||||
var nodeBottom = node.Y + node.Height;
|
||||
var distanceBelowNode = laneY - nodeBottom;
|
||||
|
||||
// Standard under-node: lane runs below node within clearance.
|
||||
var isBelow = distanceBelowNode > 0.5d && distanceBelowNode < minClearance;
|
||||
// Extended alongside: lane runs flush with (within 4px of) the
|
||||
// node's top or bottom boundary — visually "glued" to the edge.
|
||||
var isFlushBottom = distanceBelowNode >= -4d && distanceBelowNode <= 0.5d;
|
||||
var isFlushTop = laneY >= node.Y - 0.5d && laneY <= node.Y + 4d;
|
||||
if (!isBelow && !isFlushBottom && !isFlushTop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,8 @@ internal static partial class ElkShapeBoundaries
|
||||
{
|
||||
// Gateway tips read as visually detached "pin" exits/entries in the renderer.
|
||||
// Keep all gateway joins on a face interior instead of permitting any tip vertex.
|
||||
// TODO: revisit for target entries where converging edges would benefit from
|
||||
// a shared vertex entry point — requires coordinated boundary-slot changes.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user