/* ============================================================================= * B05_Profile_UI_RouteEdit_Curve_Pick.ts * 노선 편집 평면 **고른 곡선 밝힘 · 곡선 없는 교각점 삼각형**(요구 242-12 · 13 · PLAN 391-2). * * 고른 곡선(교각점 고름 · 호 누름 = 같은 `picked`) = 호 굵게 + 교각점→BC · EC 접선 + BC · MC · EC * 세 점(하늘색). `_Render` 가 노드 · 손잡이 뒤 맨 위에서 부름 — 집기(`_Input`)는 그대로. * ========================================================================== */ import type { RouteEditScene } from "./B05_Profile_UI_RouteEdit_Render"; import { curveArcVertices, curveMidVertex } from "./logic/B05_Profile_UI_RouteEdit_Curve"; import type { Vertex } from "./logic/B05_Profile_UI_RouteEdit_Curve"; /** 고름 색 — 측점 법선(`_Hover`)과 같은 하늘색. */ const PICK_COLOR = "#0ea5e9"; /** 삼각형 외접 반지름 = 노드 반지름 × 이 값 — 원과 넓이가 비슷해 보이게. */ const TRIANGLE_SCALE = 1.4; /** 곡선 없는 교각점 삼각형(391-2) — 꼭짓점 위 · 원 대신 같은 자리 · 크기. 경로만 그림. */ export function traceNodeTriangle( context: CanvasRenderingContext2D, x: number, y: number, radius: number, ): void { const r = radius * TRIANGLE_SCALE; context.moveTo(x, y - r); context.lineTo(x + r * Math.cos(Math.PI / 6), y + r / 2); context.lineTo(x - r * Math.cos(Math.PI / 6), y + r / 2); context.closePath(); } /** 고른 곡선 밝힘(391-2) — 곡선을 지운 교각점 · 고름 없음이면 안 그림. */ export function drawPickedCurve( context: CanvasRenderingContext2D, scene: RouteEditScene, style: CSSStyleDeclaration, ): void { const curve = scene.curveInfo.find((item) => item.node_first === scene.picked); if (!curve || scene.curveOn[curve.node_first] === false) return; const halo = style.getPropertyValue("--map-halo") || "rgba(255,255,255,0.9)"; const path = (points: ReadonlyArray): void => { context.beginPath(); points.forEach((vertex, index) => { const [x, y] = scene.toScreen(vertex); if (index === 0) context.moveTo(x, y); else context.lineTo(x, y); }); }; context.save(); context.strokeStyle = PICK_COLOR; context.lineWidth = 2; context.setLineDash([6, 4]); path([curve.start, curve.apex, curve.end]); context.stroke(); context.setLineDash([]); path(curveArcVertices(curve)); context.strokeStyle = halo; context.lineWidth = 8; context.stroke(); context.strokeStyle = PICK_COLOR; context.lineWidth = 5; context.stroke(); context.fillStyle = PICK_COLOR; context.strokeStyle = halo; context.lineWidth = 2; [curve.start, curveMidVertex(curve), curve.end].forEach((point) => { const [x, y] = scene.toScreen(point); context.beginPath(); context.arc(x, y, 5, 0, Math.PI * 2); context.fill(); context.stroke(); }); context.restore(); }