Files
Aislo/B05_Profile/logic/B05_Profile_UI_Profile_Pivot.ts
T
eomsangdonandClaude Opus 5.5 309415a481 fix(B05 종단): 직선 판정 한 벌(꼭짓점 높이 1e-5 m) · 끝점 꼭짓점 · 기울이기 누름 쌓임 · 편집 측점 수 (426)
- TS `logic/B05_Profile_Profile_Straight.ts` ↔ 파이썬 `is_straight_bend` 짝 · 곡선 넣기 · ▲▼ 축 · 직선 찾기
- 적용 한 곳 `tidyEdits` — 직선 위 기억 R · 0 오프셋 지움(모양 그대로)
- 직선화 · 자유지정 끝이 꼭짓점 아니면 지금 높이로 세움 · 고른 직선 기울이기 = 지금 경첩 높이 + 걸음
- 「편집 측점 N개」 = 꺾인 편집 꼭짓점 수 · 시험 test_426 + 헬퍼 스텁 넷

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
2026-10-18 15:51:08 +09:00

50 lines
2.3 KiB
TypeScript

/* =============================================================================
* B05_Profile_UI_Profile_Pivot.ts
* 종단 ▲▼ 축 찾기(355-1 · 368-1 · 요구 235-15 · 240-20) — 누른 점에서 좌우로 같은
* 기울기 마디를 건너 다음 꺾임(R 있는 점 · 없으면 시점 · 종점)을 축으로 삼는다. 사이
* 측점은 새 직선(축 → 누른 점 → 축) 위로 따라 돈다(`adjustStation`). 직선 안 점 ·
* 꼭짓점 아닌 자리(추가 측점)도 같은 규칙 — 누른 점이 새 꺾임(기본 L 곡선)이 된다.
*
* 처음 계획선은 마디마다 꺾여 축 = 누른 점 ±1 → 사이 측점 없음(옛 동작 그대로).
* `B05_Profile_UI_Profile_Alignment` 를 타입으로만 읽는다(순환 import 없음).
* ========================================================================== */
import type { ProfileAlignment } from "./B05_Profile_UI_Profile_Alignment";
import { straightAt } from "./B05_Profile_Profile_Straight";
const SAME_STATION_M = 1e-6;
export interface PivotAxes {
fromM: number;
fromZ: number;
toM: number;
toZ: number;
/** 두 축 사이(끝 · 누른 점 제외) 변화점 chainage. */
inner: number[];
}
/** 누른 점의 두 축과 사이 변화점 — 시종점 · 계획선 밖이면 null. */
export function pivotAxes(alignment: ProfileAlignment, chainageM: number): PivotAxes | null {
const { pvi } = alignment;
const index = pvi.findIndex((node) => Math.abs(node.chainage_m - chainageM) < SAME_STATION_M);
// 꼭짓점 아닌 자리 = 그 점을 품은 마디 하나가 좌우 마디
const right = index >= 0 ? index : pvi.findIndex((node) => node.chainage_m > chainageM);
if (right <= 0 || (index >= 0 && index >= pvi.length - 1)) return null;
const [leftSeg, rightSeg] = index >= 0 ? [index - 1, index] : [right - 1, right - 1];
// 이웃끼리 — 꼭짓점이 직선 위(높이 기준 · 426)면 건넘
let from = leftSeg;
while (from > 0 && straightAt(pvi, from)) from -= 1;
let to = rightSeg + 1;
while (to < pvi.length - 1 && straightAt(pvi, to)) to += 1;
return {
fromM: pvi[from].chainage_m,
fromZ: pvi[from].elevation_m,
toM: pvi[to].chainage_m,
toZ: pvi[to].elevation_m,
inner: pvi
.slice(from + 1, to)
.map((node) => node.chainage_m)
.filter((chainage) => Math.abs(chainage - chainageM) >= SAME_STATION_M),
};
}