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 nodeBottom = node.Y + node.Height;
|
||||||
var gap = laneY - nodeBottom;
|
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);
|
continue;
|
||||||
var maxX = Math.Max(path[i].X, path[i + 1].X);
|
}
|
||||||
if (maxX > node.X - 0.5d && minX < node.X + node.Width + 0.5d)
|
|
||||||
{
|
var minX = Math.Min(path[i].X, path[i + 1].X);
|
||||||
hasGatewayExitUnderNode = true;
|
var maxX = Math.Max(path[i].X, path[i + 1].X);
|
||||||
break;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var distanceBelowNode = laneY - (node.Y + node.Height);
|
var nodeBottom = node.Y + node.Height;
|
||||||
if (distanceBelowNode <= 0.5d || distanceBelowNode >= minClearance)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ internal static partial class ElkShapeBoundaries
|
|||||||
{
|
{
|
||||||
// Gateway tips read as visually detached "pin" exits/entries in the renderer.
|
// 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.
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user