From dcabce147e3a0c6d32f9b4e392ea5d120220441e Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 3 Sep 2026 19:54:13 +0900 Subject: [PATCH] =?UTF-8?q?feat(B04):=20=EC=A7=80=ED=91=9C=EB=A9=B4=203D?= =?UTF-8?q?=20=EB=B0=A9=EC=9C=84=20=ED=91=9C=EC=8B=9C=EB=A5=BC=203?= =?UTF-8?q?=EC=B6=95=20=ED=8A=B8=EB=9D=BC=EC=9D=B4=EC=96=B4=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 옛 콤파스는 방위각(`atan2(ox, oz)`)만 써서 경사에 따른 남북 압축이 빠졌음 — 사시도 프리셋(오프셋 120·95·135, 앙각 27.7°)에서 바늘 41.6°, 화면 실제 북쪽 62.4°로 20.8° 어긋났음(2026-09-03 사용자 지적). 세계 축 N(−z)·E(+x)·Z(+y)를 카메라 화면 기저(오른쪽 r, 위 u)에 투영해 선과 글자를 그림. 기저는 카메라 오프셋만으로 구함(up = +y 고정). 뒤로 누운 축(깊이 > 0.25)과 정면으로 와 짧아진 축은 흐리게 그려 겹침을 줄임. 검증: typecheck 통과. 기본 시점에서 DOM 좌표가 해석값과 일치 — N (28.0, 11.0) · E (45.0, 28.0) · Z (28.0, 27.4). 회전 중 거동은 사용자 화면 검증 대기. Co-Authored-By: Claude Opus 5 (1M context) --- B04_PreProcess/B04_PreProcess_UI_Compass.ts | 99 ++++++++++++++----- B04_PreProcess/B04_PreProcess_UI_Style.css | 27 ++--- .../B04_PreProcess_UI_TerrainViewer.ts | 6 +- 3 files changed, 93 insertions(+), 39 deletions(-) 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 = ` -