- 묶음 출력 읽기만 · ground · cross 단계 함수를 그 자리 측점 하나로 다시 부름(파생 저장 · 캐시 안 씀) - 그 자리 측점 = [측점 추가] 뒤 묶음 측점과 같은 틀 · 반경 · 확폭(logic/design_pipeline_probe_station) - 격자 없음 · 분석 지형 다름 = 서버 미리 뜨기 + 「저장 계획선 기준」 한 줄 · 창 글에 계획고 - 묶음 cross 차례마다 떠 있는 창 다시 그림 - 거울 시험 test_368_4(곡선표 있음 · 없음 · 직선 · 곡선 안) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013QyNXY2TUKXCFMwAca2APG
66 lines
2.8 KiB
TypeScript
66 lines
2.8 KiB
TypeScript
/* =============================================================================
|
|
* A00_Common/design/logic/design_pipeline_probe_station.ts
|
|
* 아무 누가거리 측점 하나(368-4) — [측점 추가] 뒤 묶음 stations 단계(`buildStations`)가 낼 그 측점과 같은
|
|
* 자리 · 틀 · 방위 · 반경 · 확폭(기존 측점 + 그 자리 누가거리로 셈) · 열쇠 = 추가 측점(`structure:plus-{m}`).
|
|
* 거울 시험 = `resources/tester/test_368_4_probe_station.py`(buildStations + 추가 측점과 대조).
|
|
* ========================================================================== */
|
|
|
|
import { stationFrameAt } from "../../../B05_Profile/logic/B05_Profile_UI_RouteEdit_Frame";
|
|
import {
|
|
curveWidenings,
|
|
designCurveWidenings,
|
|
designSpans,
|
|
planRadii,
|
|
stationKey,
|
|
} from "../../../B05_Profile/logic/B05_Profile_Sections_Stations";
|
|
import { PLUS_OWNER_PREFIX } from "../../../common_util/common_util_structure_station";
|
|
import type { DesignCurve, PipelineStation, Vertex } from "./design_pipeline_types";
|
|
|
|
const round = (value: number, digits: number): number => Number(value.toFixed(digits));
|
|
|
|
/** 그 자리 측점(지반 전) — 노선 밖이면 null. `stations` = 지금 묶음 측점(반경 · 확폭 테이퍼 이웃). */
|
|
export function probeStation(
|
|
line: ReadonlyArray<Vertex>,
|
|
curves: ReadonlyArray<DesignCurve>,
|
|
stations: ReadonlyArray<PipelineStation>,
|
|
chainageM: number,
|
|
): PipelineStation | null {
|
|
const frame = stationFrameAt(line, chainageM);
|
|
if (!frame) return null;
|
|
const chainages = [...stations.map((s) => s.chainageM), chainageM].sort((a, b) => a - b);
|
|
const index = chainages.indexOf(chainageM);
|
|
const spans = designSpans(line, curves);
|
|
let radius: number | null;
|
|
let side: "left" | "right" | null;
|
|
let widening: number;
|
|
if (spans.length) {
|
|
const out = designCurveWidenings(chainages, spans);
|
|
[radius, side, widening] = [out.radii[index], out.sides[index], out.widenings[index]];
|
|
} else {
|
|
const total = Math.max(...stations.map((s) => s.chainageM), chainageM);
|
|
const measured = planRadii(line, chainages, total);
|
|
const tapered = curveWidenings(chainages, measured.radii, measured.sides);
|
|
[radius, side, widening] = [
|
|
measured.radii[index],
|
|
tapered.sides[index],
|
|
tapered.widenings[index],
|
|
];
|
|
}
|
|
const tangent: Vertex = [frame.left[1], -frame.left[0]];
|
|
const owner = `${PLUS_OWNER_PREFIX}${Math.round(chainageM)}`;
|
|
return {
|
|
key: stationKey("structure", owner, "anchor"),
|
|
chainageM: round(chainageM, 6),
|
|
x: round(frame.origin[0], 6),
|
|
y: round(frame.origin[1], 6),
|
|
azimuthDeg: round(((Math.atan2(tangent[0], tangent[1]) * 180) / Math.PI + 360) % 360, 6),
|
|
left: [round(frame.left[0], 9), round(frame.left[1], 9)],
|
|
kind: "structure",
|
|
id: owner,
|
|
ground: null,
|
|
planRadiusM: radius,
|
|
curveOuterSide: side,
|
|
curveWideningM: widening,
|
|
};
|
|
}
|