From 2f8adc04355900f561bd212a34375f174a79ceed Mon Sep 17 00:00:00 2001 From: master <> Date: Thu, 2 Apr 2026 16:47:00 +0300 Subject: [PATCH] Remove backtrack overshoots in SVG edge rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When three consecutive points are on the same axis and the middle one overshoots then returns (e.g., Y goes 170→119→135), remove the overshoot point. This eliminates the visible inverted-U loop above the Parallel Execution Join node. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../WorkflowRenderSvgRenderer.cs | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Renderer.Svg/WorkflowRenderSvgRenderer.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Renderer.Svg/WorkflowRenderSvgRenderer.cs index b33340197..571dbc50d 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Renderer.Svg/WorkflowRenderSvgRenderer.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Renderer.Svg/WorkflowRenderSvgRenderer.cs @@ -2041,9 +2041,45 @@ public sealed class WorkflowRenderSvgRenderer // When removing a jog, snap the next point to the previous point's // axis so we get a clean L-shape instead of a diagonal. var mutablePoints = points.ToList(); - // No debug needed — the S-curve comes from the corner radius - // on short intermediate segments, not from tiny jog points. + // Remove backtracks: when three consecutive points are on the same + // axis (same X or same Y) and the middle one overshoots then returns, + // remove the overshoot point. + for (var i = 1; i < mutablePoints.Count - 1; i++) + { + var prev = mutablePoints[i - 1]; + var curr = mutablePoints[i]; + var next = mutablePoints[i + 1]; + var sameX = Math.Abs(prev.X - curr.X) < 2d && Math.Abs(curr.X - next.X) < 2d; + var sameY = Math.Abs(prev.Y - curr.Y) < 2d && Math.Abs(curr.Y - next.Y) < 2d; + if (sameX) + { + // All three on same X. Check if curr overshoots: prev→curr goes + // one direction, curr→next goes the opposite. + var d1 = curr.Y - prev.Y; + var d2 = next.Y - curr.Y; + if (d1 * d2 < 0d) // opposite directions = backtrack + { + mutablePoints.RemoveAt(i); + i--; + continue; + } + } + + if (sameY) + { + var d1 = curr.X - prev.X; + var d2 = next.X - curr.X; + if (d1 * d2 < 0d) + { + mutablePoints.RemoveAt(i); + i--; + continue; + } + } + } + + // Remove tiny jog segments (< 30px) that create visible zigzag steps. var cleaned = new List { mutablePoints[0] }; for (var i = 1; i < mutablePoints.Count; i++) {