fix(B06): 세월교 측벽을 수직으로 세운다
증상(사용자): 세월교 횡단도 측벽이 기울어 있고 바닥판 모서리도 깎여 있다. 확인 결과 세로(수직)로 그려져야 한다. 원인: 세월교 측벽은 ㄴ형 집수정 부재를 재사용한다(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) <noreply@anthropic.com>
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user