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:
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user