feat(B06): 관 접속 절·성토선 3도 물매 + 교차점 보간 + 절성토 교차 기준 자동 줌아웃
- 관 유도 접속선을 0도 → **3도**로: 유입측은 계류 쪽 오름(물이 관으로), 유출측 매몰 절토선은 계류 쪽 내림(물이 밖으로). 집수정 I형 되메움선도 동일 - 모든 유도선·성토부선 끝점을 격자점이 아니라 **선형 보간 교차점**에 붙여 선이 원지반을 미세하게 벗어나던 문제 해소(2026-08-22 사용자 지적) - 카드 자동 줌아웃: **구조물 없는 상태**의 설계 절·성토선이 원지반과 만나는 지점(+0.5m)이 표시 반폭 밖이면 그 카드만 반폭을 넓혀 그린다. 보유 샘플 범위를 넘는 경우는 기존 전역 반폭 재생성 경로(applyPanelToAll)가 담당 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,11 @@ import { computeCulvertLayout } from "./B06_Section_UI_Cross_Culvert";
|
||||
import type { CulvertLayout, InletStructureChoice, RevetKey } from "./B06_Section_UI_Cross_Culvert";
|
||||
import { materialLabel, materialLimit } from "./B06_Section_UI_Cross_Culvert_Const";
|
||||
import type { WallAdjust } from "./B06_Section_UI_Cross_Culvert_Types";
|
||||
import {
|
||||
designInterpolator,
|
||||
groundInterpolator,
|
||||
slopeToeOffset,
|
||||
} from "./B06_Section_UI_Cross_Culvert_Solve";
|
||||
/**
|
||||
* 기슭막이 4축 조작 제어(2026-08-22 확정) — 벽을 눌러 고르고 조정창에서
|
||||
* 좌우(x)·상하(d, 성토선 대각)·높이(h)·재질(m)을 만진다. 고른 벽은 여기 담아 두어
|
||||
@@ -70,15 +75,7 @@ export function computeCardCulvert(
|
||||
const layout = computeCulvertLayout(
|
||||
section,
|
||||
sourceSamples,
|
||||
revetOffset
|
||||
? {
|
||||
inlet: revetOffset.adjustFor(section, "inlet"),
|
||||
outlet: revetOffset.adjustFor(section, "outlet"),
|
||||
extras: Array.from({ length: extraWalls?.countFor(section) ?? 0 }, (_, i) =>
|
||||
revetOffset.adjustFor(section, `extra${i}`),
|
||||
),
|
||||
}
|
||||
: undefined,
|
||||
adjustsInput(section, revetOffset, extraWalls),
|
||||
inletStructure?.valueFor(section),
|
||||
equalizeExtras,
|
||||
);
|
||||
@@ -147,3 +144,41 @@ export function computeCardCulvert(
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
function adjustsInput(
|
||||
section: CrossSection,
|
||||
revetOffset?: RevetOffsetControl,
|
||||
extraWalls?: ExtraWallControl,
|
||||
): { inlet: WallAdjust; outlet: WallAdjust; extras: WallAdjust[] } | undefined {
|
||||
if (!revetOffset) return undefined;
|
||||
return {
|
||||
inlet: revetOffset.adjustFor(section, "inlet"),
|
||||
outlet: revetOffset.adjustFor(section, "outlet"),
|
||||
extras: Array.from({ length: extraWalls?.countFor(section) ?? 0 }, (_, i) =>
|
||||
revetOffset.adjustFor(section, `extra${i}`),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* **구조물 없는 상태**의 설계 절·성토선이 원지반과 만나는 지점이 들어오는 데
|
||||
* 필요한 표시 반폭(m, 여유 0.5 포함) — 2026-08-22 사용자 확정 줌 기준.
|
||||
* 구조물(기슭막이·집수정)이 어디로 가든 화면 기준은 지형·설계선이 정한다.
|
||||
*/
|
||||
export function culvertRequiredHalfWidth(section: CrossSection): number | null {
|
||||
const design = section.design;
|
||||
if (!design) return null;
|
||||
const groundAt = groundInterpolator(section.samples);
|
||||
const designAt = designInterpolator(design.design_line);
|
||||
const edges = design.road_edges;
|
||||
if (!groundAt || !designAt || !edges) return null;
|
||||
const offsets = section.samples.map((sample) => sample.offset_m ?? 0);
|
||||
const limits = { left: Math.max(...offsets), right: Math.min(...offsets) };
|
||||
let extent = 0;
|
||||
for (const side of ["left", "right"] as const) {
|
||||
const edge = side === "left" ? edges.left : edges.right;
|
||||
const toe = slopeToeOffset(designAt, groundAt, edge.offset_m, limits[side]);
|
||||
extent = Math.max(extent, Math.abs(toe));
|
||||
}
|
||||
return extent > 0 ? extent + 0.5 : null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user