From 11abd303e7d4f76409fe0bb91415427b374e4fa2 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 29 Aug 2026 13:22:50 +0900 Subject: [PATCH] =?UTF-8?q?fix(B06):=20=EC=84=B8=EC=9B=94=EA=B5=90=20?= =?UTF-8?q?=EC=B8=A1=EB=B2=BD=EC=9D=84=20=EC=88=98=EC=A7=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=84=B8=EC=9A=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 증상(사용자): 세월교 횡단도 측벽이 기울어 있고 바닥판 모서리도 깎여 있다. 확인 결과 세로(수직)로 그려져야 한다. 원인: 세월교 측벽은 ㄴ형 집수정 부재를 재사용한다(2026-08-25). 그래서 집수정 규칙인 전면 1:0.3 기움과 거기서 파생된 바닥판 taper(0.3 × 두께)가 딸려 왔다. 세월교 근거가 아니라 부재를 빌려 오며 따라온 값이다. 근거: 지식DB·교본 원문에 세월교 단면 기울기 수치는 없다. 교본 그림 3-18 세월교 설치 종단도의 구체가 수직 벽이고, 사용자가 그렇게 확정했다. 고침: buildBasin에 leanRatio 인자를 두고(기본 0.3) 세월교만 0을 넘긴다. 집수정 호출부는 인자를 안 넘기므로 동작이 그대로다. 벽 상단 도로측 꼭짓점 (설계선 트림 경계)은 노견 끝 그대로라 트림·접근선 규칙도 불변이고, 바닥 길이는 날개벽 투영 연장 + 벽 두께로 유지된다. 3D는 같은 폴리곤을 스윕하므로 자동 반영된다. Co-Authored-By: Claude Opus 5 (1M context) --- .../B06_Section_UI_Cross_Culvert_Basin.ts | 20 +++++++++++++------ B06_Section/B06_Section_UI_Cross_Ford_Geom.ts | 10 ++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/B06_Section/B06_Section_UI_Cross_Culvert_Basin.ts b/B06_Section/B06_Section_UI_Cross_Culvert_Basin.ts index 2316cc62..d789323a 100644 --- a/B06_Section/B06_Section_UI_Cross_Culvert_Basin.ts +++ b/B06_Section/B06_Section_UI_Cross_Culvert_Basin.ts @@ -88,6 +88,12 @@ export interface BasinBuildInput { memberThicknessM?: number; /** 바닥판 두께(m). 기본 = 벽 두께. 세월교는 교본 물받이 최소 0.3m를 쓴다. */ floorThicknessM?: number; + /** + * 벽 기움(1:n의 n). 기본 = 집수정 규칙 0.3. **세월교는 0**(수직) — 기움은 집수정 + * 부재를 재사용하며 딸려 온 값이고, 교본 그림 3-18 세월교 단면은 수직 벽이다 + * (2026-08-30 사용자 확정: 집수정은 그대로 두고 세월교만 세운다). + */ + leanRatio?: number; } /** 집수정 구성 결과 — 본체가 트림·관 끝단면·관 시작점에 나눠 꽂는다. */ @@ -127,6 +133,8 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { cutSlopeRatio, adjust, } = input; + /** 이 부재의 기움 — 집수정 0.3, 세월교 0(수직). */ + const lean = input.leanRatio ?? REVET_LEAN_RATIO; const movedAnchor = { offset: baseAnchor.offset + outward * (adjust.lateralM + adjust.slopeM), elevation: baseAnchor.elevation - adjust.slopeM / 1.2, @@ -147,7 +155,7 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { dir: number, bottomElevation = defaultBottom, ): OffsetPoint[] => { - const topShift = -dir * REVET_LEAN_RATIO * wallHeight; + const topShift = -dir * lean * wallHeight; const spanZ = wallHeight + floorThickness; const xAt = (elevation: number): number => baseOffset + topShift * ((elevation - defaultBottom) / spanZ); @@ -166,7 +174,7 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { }; // I형 벽 자리 = **상단 도로측 꼭짓점이 노견 끝 지점에 닿는다**(2026-08-22 사용자 // 확정). 벽 상단이 도로측으로 1:0.3 물러나므로 하단(base)은 그만큼 계류측 바깥. - const wallBase = anchor.offset + outward * (REVET_LEAN_RATIO * wallHeight); + const wallBase = anchor.offset + outward * (lean * wallHeight); // I형 벽 하단은 **원지반까지 묻는다**(2026-08-22 사용자 — 지반 아래 부재두께만큼 // 근입 후 배관을 둔다). ㄴ·ㄷ형은 바닥판이 원지반을 대체하므로 현행 유지. const iWallBottom = @@ -203,12 +211,12 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { const wallOuterAt = (elevation: number): number => { const bottom = anchor.elevation - floorThickness; const t = (elevation - bottom) / (wallHeight + floorThickness); - return wallBase + outward * memberT - outward * REVET_LEAN_RATIO * wallHeight * t; + return wallBase + outward * memberT - outward * lean * wallHeight * t; }; const floorTopInner = wallOuterAt(anchor.elevation); const floorBottomInner = wallOuterAt(anchor.elevation - floorThickness); const floorOuter = floorTopInner + outward * (adjust.innerWidthM + memberT); - const floorTaper = REVET_LEAN_RATIO * floorThickness; + const floorTaper = lean * floorThickness; if (shape !== "I") { parts.push({ kind: "floor", @@ -240,7 +248,7 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { const refTop = shape === "U" ? { - offset: mirroredWallBase + outward * REVET_LEAN_RATIO * wallHeight, + offset: mirroredWallBase + outward * lean * wallHeight, elevation: anchor.elevation + wallHeight, } : { offset: floorOuter, elevation: anchor.elevation }; @@ -289,7 +297,7 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult { : { offset: floorTopInner, elevation: anchor.elevation }, fillStart, fillBottomElevation: anchor.elevation - floorThickness, - trimOffset: wallBase - outward * REVET_LEAN_RATIO * wallHeight, + trimOffset: wallBase - outward * lean * wallHeight, trimElevation: anchor.elevation + wallHeight, }; } diff --git a/B06_Section/B06_Section_UI_Cross_Ford_Geom.ts b/B06_Section/B06_Section_UI_Cross_Ford_Geom.ts index 6c480525..f862cce8 100644 --- a/B06_Section/B06_Section_UI_Cross_Ford_Geom.ts +++ b/B06_Section/B06_Section_UI_Cross_Ford_Geom.ts @@ -4,8 +4,10 @@ * 백엔드 `section.ford` 제원을 좌표로 옮긴다(치수 결정 금지). * * 구성(2026-08-25 사용자 확정): - * · 양측 **측벽** = ㄴ형 집수정을 그대로 재사용한다(`buildBasin`) — 전면 1:0.3 - * 기움·좌우·상하(대각) 이동·계류측 성토부선이 집수정과 같은 규칙으로 따라온다. + * · 양측 **측벽** = ㄴ형 집수정 부재를 재사용한다(`buildBasin`) — 좌우·상하(대각) + * 이동·계류측 성토부선이 집수정과 같은 규칙으로 따라온다. 단 **벽은 수직**이다 + * (`leanRatio: 0` — 2026-08-30 사용자 확정, 교본 그림 3-18). 집수정의 1:0.3 + * 기움은 세월교 근거가 아니라 부재를 빌려 오며 딸려 온 값이었다. * · **바닥판** = 두 측벽 사이를 잇는 판 + 각 측 바깥으로 **날개벽 투영**(길이×cos각) * 만큼 뻗은 판. 집수정 내공 폭 자리에 그 연장량을 넣어 같은 기하로 만든다. * · **관**은 바닥판 상면(측벽 바깥면)에 안히고, 관 위 ~ 노면 아래는 **성토(노체)** 다. @@ -187,6 +189,10 @@ export function computeFordLayout( }, memberThicknessM: ford.wall_thickness_m, floorThicknessM: ford.slab_thickness_m, + // 세월교 측벽은 **수직**이다(2026-08-30 사용자 확정 — 교본 그림 3-18 세월교 + // 단면). 1:0.3 기움은 ㄴ형 집수정 부재를 재사용하며 딸려 온 값이라 여기서 끈다. + // 바닥판 taper(0.3×두께)도 같은 값에서 나오므로 함께 사라져 직사각형이 된다. + leanRatio: 0, }); const wall = built.basin.parts.find((part) => part.kind === "wall"); const floor = built.basin.parts.find((part) => part.kind === "floor");