fix(B06): 세월교 · 박스 유입 수평공간 시작 = 본체 바닥 높이 흙막이 전면(89-3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
This commit is contained in:
2026-10-08 12:05:09 +09:00
co-authored by Claude Opus 5.5
parent 7d761e39af
commit f54def5b2b
4 changed files with 38 additions and 1 deletions
@@ -271,3 +271,20 @@ export function withoutGuardedFill<T extends BoxLayout | FordLayout>(
label: { ...ford.label, text: `${ford.label.text} L${Math.ceil(lengthM - 1e-6)}m` },
} as T;
}
/** 세월교 · 박스 유입 흙막이 수평공간 시작 = 본체 바닥(세월교 바닥판 · 박스 저판 상면) 높이의
* 흙막이 전면 자리(89-3). 본체가 이 측점에 없으면 null(배관 규칙). */
export function guardFloorStart(
section: CrossSection,
base: BodyGuardBase | null,
wall: WallLayout,
): OffsetPoint | null {
const end = base?.ends.inlet;
if (!end) return null;
const slab = section.culvert?.body === "box" ? (section.box?.slab_thickness_m ?? 0) : 0;
const floor = end.invert + slab;
return {
offset: wall.points[2].offset + wall.outward * wall.lean * (wall.topJoint.elevation - floor),
elevation: floor,
};
}
@@ -25,6 +25,7 @@ import { buildRevetWallGeometry } from "./B06_Section_UI_Cross_Wall";
import {
bodyGuardAxes,
bodyGuardBase,
guardFloorStart,
bodyGuardHeight,
fordPipeFit,
mergeGuardTrim,
@@ -596,7 +597,7 @@ export function computeCulvertLayout(
outletBottom: outletWall?.bottomBack.elevation ?? 0,
basinStart: culvert.hidden_pipe
? inletWall
? pipeCorners.inlet.bottom
? (guardFloorStart(section, body, inletWall) ?? pipeCorners.inlet.bottom)
: null
: basinFillStart,
basinBottom: culvert.hidden_pipe ? (inletWall?.bottomBack.elevation ?? 0) : basinFillBottom,
@@ -154,6 +154,19 @@ out.cutBerm2 = cutTails(
sections.map((s) => (s === at(352.14) ? berm2 : s)),
);
// ⑤b 유입 수평공간 시작 높이 = 본체 바닥(세월교 바닥판 상면 · 박스 저판 상면 · 89-3)
out.inletFloor = [352.14, 173.087].map((chainage) => {
const section = at(chainage);
const layouts = computeStoredLayouts(section, sections);
const start = layouts.culvert.basinFill.segments[0]?.points[0];
const inletLeft = (section.uphill_side ?? "left") === "left";
const floor = layouts.ford
? layouts.ford.sides.find((s) => s.role === "inlet").slabTopElevation
: layouts.box.sides.find((s) => (s.role === "left") === inletLeft).bottomElevation +
layouts.box.box.slab_thickness_m;
return { start: start ? r3(start.elevation) : null, floor: r3(floor) };
});
// ⑥ 관 보호공 기본 자리 = 제일 위(성토선 0 지점 · d 0) · 관 길이 m 단위
const pipe = clone(at(180));
pipe.culvert = {
+6
View File
@@ -87,6 +87,12 @@ def test_흙막이_끝_절토는_수평공간_뒤(shape: dict) -> None:
assert tail["berm"] == pytest.approx(2.0, abs=1e-3)
def test_유입_수평공간_시작은_본체_바닥(shape: dict) -> None:
"""89-3 — 박스 저판 상면 · 세월교 바닥판 상면 높이에서 수평 → 절토."""
for case in shape["inletFloor"]:
assert case["start"] == pytest.approx(case["floor"], abs=1e-3)
def test_관_보호공_기본_자리는_제일_위(shape: dict) -> None:
pipe = shape["pipe"]
assert pipe is not None