From 81e0bd0f3d78f6cdf030e3f1b17db1cbeb50ce83 Mon Sep 17 00:00:00 2001 From: igurielidze Date: Mon, 30 Mar 2026 15:14:25 +0400 Subject: [PATCH] Stabilize EPC waypoint dragging: constrain endpoints to slide along segment - First/last waypoints now only extend/shorten along their segment direction, preventing unwanted rotation of the end boxes - Middle waypoints remain freely draggable for direction changes - Add default middle waypoint so new EPCs have 3 control points Co-Authored-By: Claude Opus 4.6 (1M context) --- svelte-app/src/lib/canvas/interactions.ts | 20 ++++++++++++++++++++ svelte-app/src/lib/symbol-config.ts | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/svelte-app/src/lib/canvas/interactions.ts b/svelte-app/src/lib/canvas/interactions.ts index 82231d9..c4559aa 100644 --- a/svelte-app/src/lib/canvas/interactions.ts +++ b/svelte-app/src/lib/canvas/interactions.ts @@ -469,6 +469,26 @@ function onMousemove(e: MouseEvent) { localY = worldSnappedY - sym.y; } + // Constrain first/last waypoint to slide along their segment direction only + // (extend/shorten without rotating the end boxes) + if (wpIdx === 0 && wps.length >= 2) { + const next = wps[1]; + const dx = wps[0].x - next.x, dy = wps[0].y - next.y; + const len = Math.sqrt(dx * dx + dy * dy) || 1; + const ux = dx / len, uy = dy / len; + const dot = (localX - next.x) * ux + (localY - next.y) * uy; + localX = next.x + ux * dot; + localY = next.y + uy * dot; + } else if (wpIdx === wps.length - 1 && wps.length >= 2) { + const prev = wps[wps.length - 2]; + const dx = wps[wpIdx].x - prev.x, dy = wps[wpIdx].y - prev.y; + const len = Math.sqrt(dx * dx + dy * dy) || 1; + const ux = dx / len, uy = dy / len; + const dot = (localX - prev.x) * ux + (localY - prev.y) * uy; + localX = prev.x + ux * dot; + localY = prev.y + uy * dot; + } + wps[wpIdx] = { x: localX, y: localY }; // Recalculate bounding box recalcEpcBounds(sym); diff --git a/svelte-app/src/lib/symbol-config.ts b/svelte-app/src/lib/symbol-config.ts index 394514e..cb11d42 100644 --- a/svelte-app/src/lib/symbol-config.ts +++ b/svelte-app/src/lib/symbol-config.ts @@ -6,8 +6,9 @@ export const EPC_CONFIG = { rightBox: { w: 10, h: 20 }, lineWidth: 1.5, defaultWaypoints: [ - { x: 26, y: 10 }, // exit from left box center-right - { x: 57, y: 10 }, // entry to right box center-left + { x: 26, y: 10 }, // exit from left box center-right + { x: 41.5, y: 10 }, // middle control point + { x: 57, y: 10 }, // entry to right box center-left ], } as const;