fix(B06): I형 집수정 관 하단을 벽면 안으로 제한 — 관이 벽을 관통하게
관 하단 자리는 벽 계류측 변과 원지반의 교점인데, 원지반이 벽 상단보다 높은 자리에서는 교점이 벽 상단으로 밀려 관이 벽 위에 얹혔다(측벽과 배관이 만나지 않음). ㄴ·ㄷ형은 관이 바닥판 윗면에서 시작해 벽 안에 물리는 것과 대비된다. 교점을 벽 상단에서 관경+여유(0.5m)만큼 아래로 제한한다. 원지반이 그보다 낮으면 종전대로 교점을 그대로 쓴다. 벽을 키우는 방향은 벽이 1:0.3으로 기울어 base가 계류측으로 밀리며 지반 교점이 함께 올라가 벽이 7.5m까지 자라 폐기했다. 검증 — 공용 브라우저 B06 I형 8개 단면 실측: 관 유입측 끝단과 벽의 세로 겹침 18.1~56.4px(수정 전 0 — 벽 위로 이탈). ㄴ형 대조(13+4.1을 조정창에서 ㄴ형으로 바꿔 확인) 겹침 유지, 확인 후 세션값 원복. pytest 370 passed·17 skipped, typecheck·prettier 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,21 +174,15 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult {
|
||||
};
|
||||
// I형 벽 자리 = **상단 도로측 꼭짓점이 노견 끝 지점에 닿는다**(2026-08-22 사용자
|
||||
// 확정). 벽 상단이 도로측으로 1:0.3 물러나므로 하단(base)은 그만큼 계류측 바깥.
|
||||
const wallBase = anchor.offset + outward * (lean * wallHeight);
|
||||
const wallBaseAt = (height: number): number => anchor.offset + outward * (lean * height);
|
||||
// I형 벽 하단은 **원지반까지 묻는다**(2026-08-22 사용자 — 지반 아래 부재두께만큼
|
||||
// 근입 후 배관을 둔다). ㄴ·ㄷ형은 바닥판이 원지반을 대체하므로 현행 유지.
|
||||
const iWallBottom =
|
||||
shape === "I"
|
||||
? Math.min(anchor.elevation, groundAt(wallBase), groundAt(wallBase + outward * memberT)) -
|
||||
floorThickness
|
||||
: defaultBottom;
|
||||
const parts: BasinLayout["parts"] = [
|
||||
{ kind: "wall", points: wallOf(wallBase, outward, iWallBottom) },
|
||||
];
|
||||
const iWallPoints = parts[0].points;
|
||||
const iGroundIntersection = (): OffsetPoint => {
|
||||
const low = iWallPoints[3];
|
||||
const high = iWallPoints[2];
|
||||
const iBottomAt = (base: number): number =>
|
||||
Math.min(anchor.elevation, groundAt(base), groundAt(base + outward * memberT)) - floorThickness;
|
||||
/** 벽 계류측 변(하단-전면 → 상단-전면)과 원지반의 교점 — I형 관 하단 자리. */
|
||||
const groundOnFace = (points: OffsetPoint[]): OffsetPoint => {
|
||||
const low = points[3];
|
||||
const high = points[2];
|
||||
let lo = 0;
|
||||
let hi = 1;
|
||||
for (let pass = 0; pass < 32; pass += 1) {
|
||||
@@ -206,6 +200,34 @@ export function buildBasin(input: BasinBuildInput): BasinBuildResult {
|
||||
elevation: low.elevation + (high.elevation - low.elevation) * t,
|
||||
};
|
||||
};
|
||||
const wallBase = wallBaseAt(wallHeight);
|
||||
const iWallBottom = shape === "I" ? iBottomAt(wallBase) : defaultBottom;
|
||||
const parts: BasinLayout["parts"] = [
|
||||
{ kind: "wall", points: wallOf(wallBase, outward, iWallBottom) },
|
||||
];
|
||||
const iWallPoints = parts[0].points;
|
||||
/** 벽 계류측 변 위에서 그 표고에 해당하는 점 — 관 하단을 벽면을 따라 내릴 때 쓴다. */
|
||||
const pointOnFaceAt = (elevation: number): OffsetPoint => {
|
||||
const low = iWallPoints[3];
|
||||
const high = iWallPoints[2];
|
||||
const span = high.elevation - low.elevation;
|
||||
const t = span > 1e-9 ? Math.min(Math.max((elevation - low.elevation) / span, 0), 1) : 0;
|
||||
return {
|
||||
offset: low.offset + (high.offset - low.offset) * t,
|
||||
elevation: low.elevation + span * t,
|
||||
};
|
||||
};
|
||||
/**
|
||||
* I형 관 하단 자리 = 벽 계류측 변과 원지반의 교점. 다만 **관이 벽을 관통해야** 하므로
|
||||
* (ㄴ·ㄷ형은 바닥판 위에서 이미 물린다) 벽 상단에서 관경+여유만큼 아래로 제한한다.
|
||||
* 원지반이 벽 상단보다 높은 자리에서 제한이 없으면 관이 벽 위로 떠 벽과 만나지 않았다
|
||||
* (2026-09-03 사용자 지적: 「측벽과 배관의 형상이 교차하고 있어야 함」).
|
||||
*/
|
||||
const iGroundIntersection = (): OffsetPoint => {
|
||||
const hit = groundOnFace(iWallPoints);
|
||||
const invertCeiling = anchor.elevation + wallHeight - (diameterM + REVET_FREEBOARD_M);
|
||||
return hit.elevation <= invertCeiling ? hit : pointOnFaceAt(invertCeiling);
|
||||
};
|
||||
// ㄴ형 = I형 + 바닥판. 바닥은 벽 바깥(계류측) 변에 맞대고 그 너머로 뻗는다
|
||||
// (2026-08-20 확정). 벽이 기울어 있어 안쪽 변도 벽 바깥면 선을 그대로 따른다.
|
||||
const wallOuterAt = (elevation: number): number => {
|
||||
|
||||
Reference in New Issue
Block a user