feat(B06): 곡선부 확폭에 앞뒤 10m 테이퍼 추가

별표2 는 확폭량 표만 주고 붙이는 방식이 없어, 곡선 시·종점에서 폭이 뚝 끊겼다.
곡선 앞뒤 CURVE_WIDENING_TAPER_M(10m) 구간에서 0 → W 로 잇는다.

- 측점 생성 때 확폭량을 한 번에 계산해 curve_widening_m 으로 저장. 테이퍼는
  이웃 측점을 봐야 하므로 측점 단위 계산으로는 낼 수 없다.
- 설계 엔진(파이썬·TS 짝)이 저장된 확폭량을 우선 쓰고, 없으면 반경 표값으로
  되돌아간다 — 옛 저장분도 그대로 돈다.

검증: pytest 389 passed(테이퍼 경계값 테스트 2건 추가), tsc --noEmit 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-06 15:02:58 +09:00
co-authored by Claude Opus 5
parent dd61754705
commit bdbefd9472
6 changed files with 87 additions and 5 deletions
+8 -1
View File
@@ -86,6 +86,8 @@ export interface CrossDesignOptions {
planRadiusM?: number | null;
/** 곡선 **바깥쪽**("left"/"right") — 확폭이 붙는 쪽(2026-09-06 사용자 확정). */
curveOuterSide?: "left" | "right" | null;
/** 저장된 확폭량(m) — 곡선 앞뒤 테이퍼가 얹힌 값. 있으면 반경 표값 대신 쓴다. */
curveWideningM?: number | null;
}
export interface CrossDesignEdge {
@@ -271,8 +273,13 @@ export function computeCrossDesign(
// 곡선부 확폭 — 표는 하한이고, 확폭을 더한 유효너비가 법정 상한(5m)을 넘지 않게 자른다.
// 짝: 파이썬 `compute_cross_design`. 표·상한 값은 config 한 곳에서 온다.
const outerSide = options.curveOuterSide;
// 저장된 확폭량(테이퍼 포함)이 있으면 그것을 쓰고, 없으면 반경 표값으로 되돌아간다.
let widening =
outerSide === "left" || outerSide === "right" ? curveWideningM(options.planRadiusM) : 0;
outerSide === "left" || outerSide === "right"
? typeof options.curveWideningM === "number" && Number.isFinite(options.curveWideningM)
? options.curveWideningM
: curveWideningM(options.planRadiusM)
: 0;
if (widening > 0) {
widening = Math.min(widening, Math.max(CURVE_WIDENING_MAX_WIDTH_M - group.road_width_m, 0));
}