diff --git a/D03_PlanAnalysis/D03_PlanAnalysis_UI_Draw.ts b/D03_PlanAnalysis/D03_PlanAnalysis_UI_Draw.ts index 484d8809b..b6a0d0916 100644 --- a/D03_PlanAnalysis/D03_PlanAnalysis_UI_Draw.ts +++ b/D03_PlanAnalysis/D03_PlanAnalysis_UI_Draw.ts @@ -4,7 +4,8 @@ * * 본선 = D02 시점에서 · D02 종점 둘레(SNAP_PX)에 오면 종점에 붙고 그 점에서 끝. * 미리보기 = 마지막 점 → 마우스 길이(m) · 원지반 기울기(%, + 오르막) — 제약 칸 넷: - * 자유 · 길이 고정 · 기울기 고정(마우스 방향 첫 자리) · 둘 다(양각기 원 위 후보 중 마우스에 가까운 것). + * 자유 · 길이 고정 · 기울기 고정(마우스 방향 첫 자리) · 둘 다(양각기 원 위 후보 중 마우스에 가까운 것) · + * 제약 기울기 = 오르내림 같은 크기(562-1 짝이 |기울기|로 셈) · 미리보기 값은 + 오르막 / − 내리막. * 갈래 = 기존 선 꺾임점(선 위면 꺾임점 끼움)을 눌러 시작 · 구역 마크 = 선 위 누름(오른쪽 = 지움). * 키 = Enter 끝 · Esc 이번 긋기 취소 · Backspace 마지막 점 빼기(설정 창 단축키 표 D03 줄). * 셈 = 562-1 짝(`logic/D03_PlanAnalysis_Draw`) · 꼴 다루기 = `logic/D03_PlanAnalysis_Plan` · @@ -165,7 +166,7 @@ export function createPlanDraw(params: PlanDrawParams): PlanDraw { }); lengthField.input.dataset.role = "draw-length"; const slopeField = createInputField({ - label: "기울기(+ 오르막)", + label: "기울기(± 같음)", type: "number", value: String(slopePct), unit: "%", @@ -240,10 +241,10 @@ export function createPlanDraw(params: PlanDrawParams): PlanDraw { point = fixedLengthPoint(from, cursor, lengthM); } else if (kind === "slope") { point = fixedSlopePoint(from, cursor, slopePct, z); - if (!point) note = `이 방향엔 ${signed(slopePct)} % 자리 없음`; + if (!point) note = `이 방향엔 ±${fmt(Math.abs(slopePct))} % 자리 없음`; } else if (kind === "both") { point = compassPoint(from, cursor, lengthM, slopePct, z); - if (!point) note = `반지름 ${fmt(lengthM)} m 원 위에 ${signed(slopePct)} % 자리 없음`; + if (!point) note = `반지름 ${fmt(lengthM)} m 원 위에 ±${fmt(Math.abs(slopePct))} % 자리 없음`; } const at = point ?? cursor; const length = segmentLength(from, at); @@ -268,7 +269,14 @@ export function createPlanDraw(params: PlanDrawParams): PlanDraw { let bestPx = LINE_HIT_PX; params.network().lines.forEach((line, index) => { if (line.vertices.length < 2) return; - const vertex = line.vertices.findIndex((v) => near(map.toScreen(v), [px, py], SNAP_PX)); + // 붙는 반경 안 꺾임점 중 가장 가까운 것 + let vertex = -1; + let vertexPx = SNAP_PX; + line.vertices.forEach((v, i) => { + const [vx, vy] = map.toScreen(v); + const d = Math.hypot(vx - px, vy - py); + if (d <= vertexPx) [vertex, vertexPx] = [i, d]; + }); const atM = vertex >= 0 ? lineLength(line.vertices.slice(0, vertex + 1))