diff --git a/B04_PreProcess/B04_PreProcess_UI_Compass.ts b/B04_PreProcess/B04_PreProcess_UI_Compass.ts index 92c98b5d..11f6c740 100644 --- a/B04_PreProcess/B04_PreProcess_UI_Compass.ts +++ b/B04_PreProcess/B04_PreProcess_UI_Compass.ts @@ -1,49 +1,96 @@ -/* B04 지표면 3D 뷰어 방위 콤파스 — 바늘이 늘 도북(N)을 가리킨다. +/* B04 지표면 3D 뷰어 방위 표시 — 카메라 자세를 그대로 따르는 **3축 트라이어드**. * - * 뷰어 좌표 규약은 백엔드 scene_vertices와 같다: x, 높이, -y. 그래서 세계에서 북쪽은 - * **-z** 다. 화면 위쪽은 카메라가 보는 수평 방향이므로, 카메라 오프셋(카메라 − 타깃)만 - * 알면 북쪽이 화면에서 몇 도 돌아가 있는지 나온다 — `Math.atan2(offset.x, offset.z)`. - * (기본 시점 offset=(0, d, d·tilt)면 0° = 북쪽이 화면 위, 카메라가 동쪽으로 가면 +90°.) + * 종전에는 방위각만으로 도는 평면 콤파스였다. 3D 화면은 기울어 있어 남북이 화면에서 + * 눌리는데(사시도 앙각 27.7° → 0.47배) 바늘은 안 눌린 각도로 돌아, 실제 화면 북쪽과 + * 최대 20.8° 어긋났다(2026-09-03 사용자 지적·실측). 축을 카메라 기저에 투영해 그리면 + * 그 어긋남이 원리적으로 사라진다. + * + * 뷰어 좌표 규약은 백엔드 scene_vertices와 같다: x(동), 높이, -y. 그래서 세계에서 + * 북쪽은 **-z**, 동쪽은 **+x**, 표고는 **+y** 다. 카메라 오프셋(카메라 − 타깃)만 있으면 + * 화면 기저를 만들 수 있다(up = +y 고정): + * · 오른쪽 r = (oz, 0, −ox)/h, 위 u = (−ox·oy, h², −oz·oy)/(h·L) + * · 화면 좌표 = (v·r, v·u), 깊이 = v·(−offset)/L — 양수면 시선 방향(뒤)이라 흐리게. * * 뷰어 파일이 이미 900줄을 넘어 여기로 뺐다(CLAUDE.md 4장 700줄 제한). */ export interface TerrainCompass { root: HTMLElement; - /** 카메라 오프셋(카메라 위치 − 타깃)으로 바늘 각도를 맞춘다. */ - update(offsetX: number, offsetZ: number): void; + /** 카메라 오프셋(카메라 위치 − 타깃)으로 축 방향을 맞춘다. */ + update(offsetX: number, offsetY: number, offsetZ: number): void; setVisible(visible: boolean): void; } -const NEEDLE_SVG = ` -