fix(B05 평면 측점 스냅): 끌기 · 방향키 하한 검사 = 맞추기 전 노선 — 10 m · 측점 No. 미리보기가 IP 를 밀어 헛걸리던 것 (390-5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
This commit is contained in:
2026-10-17 20:11:30 +09:00
co-authored by Claude Opus 5.5
parent e3b8123f8b
commit a8a8e4faba
4 changed files with 39 additions and 9 deletions
+16 -6
View File
@@ -29,8 +29,8 @@ interface Hold {
index: number;
before: Vertex[];
start: Vertex;
/** 키로 옮긴 자리(맞추기 전) — 다음 걸음은 여기서(맞춤이 쌓이지 않음). */
at: Vertex;
/** 스냅 미리보기 전 노선(맞추기 전) — 다음 걸음 · 하한 검사는 여기서(맞춤이 쌓이지 않음). */
raw: Vertex[] | null;
moved: boolean;
}
@@ -41,15 +41,25 @@ export function bindRouteEditKeys(params: RouteEditPointerParams, dragging: () =
const metricAt = (x: number, y: number): Vertex => params.toMetric(...params.unrotate(x, y));
/** 스냅 미리보기 — 맞추기 전 노선을 쥔 뒤 맞춤(끔이면 쥐지 않음). */
function fitPreview(now: Hold, planned: Vertex[]): void {
const raw = planned.map((vertex): Vertex => [vertex[0], vertex[1]]);
now.raw = params.fitDrag(now.index) ? raw : null;
}
/** 한 걸음 — 하한을 새로 깨면 그 걸음만 되돌림(끌기와 같은 검사). */
function step(now: Hold): void {
const state = params.state();
if (now.raw) {
now.raw.forEach((vertex, index) => (state.planned[index] = vertex));
params.markEdited();
}
const node = state.planned[now.index];
if (!node) return;
const snapStepM = params.stations() !== null ? params.snapStepM() : undefined;
const [dx, dy] = arrowStep(now.key, now.shift, metricAt, snapStepM);
const before = curveShortfalls(state.nodeInfo, state.limitRadiusM, state.limitArcM);
state.planned[now.index] = [now.at[0] + dx, now.at[1] + dy];
state.planned[now.index] = [node[0] + dx, node[1] + dy];
params.markEdited();
const after = params.state();
if (
@@ -57,6 +67,7 @@ export function bindRouteEditKeys(params: RouteEditPointerParams, dragging: () =
) {
state.planned[now.index] = node;
params.markEdited();
fitPreview(now, state.planned);
status.textContent =
`${params.routeHead()} — 하한에 걸려 더 못 옮깁니다` +
`(곡선반지름 ${state.limitRadiusM}m${state.limitArcM > 0 ? ` · 곡선 길이 ${state.limitArcM}m` : ""}).`;
@@ -64,8 +75,7 @@ export function bindRouteEditKeys(params: RouteEditPointerParams, dragging: () =
return;
}
now.moved = true;
now.at = state.planned[now.index];
params.fitDrag(now.index);
fitPreview(now, state.planned);
status.textContent = `${params.routeHead()} — 방향키로 옮기는 중(뗄 때 한 걸음). ${params.curveHint()}`;
params.draw();
}
@@ -112,7 +122,7 @@ export function bindRouteEditKeys(params: RouteEditPointerParams, dragging: () =
index,
before: state.planned.map(([x, y]): Vertex => [x, y]),
start: [node[0], node[1]],
at: [node[0], node[1]],
raw: null,
moved: false,
};
hold = now;