feat(B06): I형 관 하단 수평 되메움선 — 지반 교점 절단 철회
- 지반 교점 절단(직전 커밋)은 사용자 확인 후 철회 — 관 끝은 벽 안쪽 변 절단으로 복귀. - 대신 관 유입 하단 꼭짓점이 원지반 위에 뜨면 그 표고 그대로 계류측으로 **수평 되메움(성토)선**을 그어 원지반과 연결(applyBasinPipeFill — Basin 분리, Geom 700줄 유지). - 검증: 13+15.7 I형 실화면 — 성토선 수평·관 꼭짓점 부착 0.4px, 스크린샷. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -239,7 +239,10 @@ export function appendCulvertOverlay(
|
||||
fill.setAttribute("y2", String(toDisplayY(basin.fillLine.to.elevation)));
|
||||
fill.setAttribute("class", "b06-chart__design-cross");
|
||||
const fillTitle = document.createElementNS(SVG_NS, "title");
|
||||
fillTitle.textContent = `집수정(${shapeName}) 성토(되메움)선 — 구조물이 원지반 밖으로 나와 5° 경사로 채움`;
|
||||
fillTitle.textContent =
|
||||
basin.shape === "I"
|
||||
? "집수정(I형) 되메움(성토)선 — 관 하단에서 수평으로 원지반과 연결"
|
||||
: `집수정(${shapeName}) 성토(되메움)선 — 구조물이 원지반 밖으로 나와 5° 경사로 채움`;
|
||||
fill.append(fillTitle);
|
||||
layer.append(fill);
|
||||
}
|
||||
|
||||
@@ -250,3 +250,24 @@ export function inletChoiceAvailability(input: {
|
||||
});
|
||||
return { revetAllowed, basinLUAllowed: probe.basin.cutLine != null, revetAutoOffset };
|
||||
}
|
||||
|
||||
/**
|
||||
* I형 집수정의 **관 하단 수평 되메움(성토)선**(2026-08-22 사용자). 관 유입 하단
|
||||
* 꼭짓점이 원지반 위에 뜨면 그 표고 그대로 계류측으로 나가 원지반과 만나는 점까지
|
||||
* 잇고, 그 아래를 성토로 본다. 지반 교점 절단 방식은 보고 후 철회.
|
||||
*/
|
||||
export function applyBasinPipeFill(
|
||||
basin: BasinLayout,
|
||||
corner: OffsetPoint,
|
||||
outward: number,
|
||||
groundAt: (offset: number) => number,
|
||||
): void {
|
||||
if (basin.shape !== "I" || corner.elevation <= groundAt(corner.offset) + 0.02) return;
|
||||
for (let run = 0.05; run <= 30; run += 0.05) {
|
||||
const probe = corner.offset + outward * run;
|
||||
if (groundAt(probe) >= corner.elevation) {
|
||||
basin.fillLine = { from: corner, to: { offset: probe, elevation: corner.elevation } };
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ export * from "./B06_Section_UI_Cross_Culvert_Const";
|
||||
export * from "./B06_Section_UI_Cross_Culvert_Types";
|
||||
|
||||
import {
|
||||
applyBasinPipeFill,
|
||||
BASIN_INNER_WIDTH_M,
|
||||
buildBasin,
|
||||
inletChoiceAvailability,
|
||||
@@ -137,16 +138,12 @@ export function computeCulvertLayout(
|
||||
: ruleReason;
|
||||
// 집수정 형식 기본값 = ㄴ(L)형(2026-08-20 확정) — 선택 시 그 형식.
|
||||
const basinShape: BasinShape = choice === "I" || choice === "L" || choice === "U" ? choice : "L";
|
||||
// ㄴ·ㄷ형은 **측면·바닥 사이즈를 유지한 채 통째로 노견 끝점에 일치**시킨다(2026-08-22
|
||||
// 사용자 확정 — 노견과 빈 공간을 채운다). 바닥(=관 유입 invert)이 따라 올라가므로
|
||||
// 관 물매도 바뀐다. 유출단은 원지반 위 원칙 그대로. I형은 원지반 배관을 유지하고
|
||||
// 벽 높이로만 노견에 연결한다(buildWall).
|
||||
// ㄴ·ㄷ형은 사이즈 유지한 채 통째로 노견 끝점 일치(2026-08-22 확정) — 바닥(=관
|
||||
// 유입 invert)이 따라 올라 물매도 바뀐다. I형은 원지반 배관 유지(상세 Basin 참조).
|
||||
if (basinReason && basinShape !== "I") {
|
||||
inlet.elevation = inletInfo.edge.elevation_m - BASIN_INNER_HEIGHT_M;
|
||||
} else if (basinReason) {
|
||||
// I형 — 관 시작점(내공 1.0m 자리) invert는 **그 x의 원지반 위**에 앉힌다(토피
|
||||
// 상한 이내). 종전에는 노견 x의 원지반을 써서 지반이 오르내리는 자리에서 관이
|
||||
// 지반에 파묻히거나 떴다(2026-08-22 사용자 ② — 13+15.7 확인).
|
||||
// I형 — 관 시작점(내공 1.0m 자리) invert = 그 x의 원지반(토피 상한 이내).
|
||||
const startOffset = inlet.offset + inletInfo.outward * BASIN_INNER_WIDTH_M;
|
||||
inlet.elevation = Math.min(groundAt(startOffset), invertCap(inletInfo.edge));
|
||||
}
|
||||
@@ -475,26 +472,6 @@ export function computeCulvertLayout(
|
||||
};
|
||||
};
|
||||
deriveAxis();
|
||||
// I형 집수정: 관 유입 끝의 마감면을 **관 하단선이 원지반과 만나는 점**으로 옮긴다
|
||||
// (2026-08-22 사용자 — 관 파란선 시작 꼭짓점이 지반 녹색선 위에 있어야 한다).
|
||||
// invert가 토피 상한에 걸려 지반보다 낮으면 벽 변에서 자른 꼭짓점이 지반과 떠서
|
||||
// 어긋나 보였다. 마감면 기울기(벽과 나란)는 유지하고 기준점만 교점으로 바꾼다.
|
||||
if (basin && basinShape === "I" && endFaces.inlet) {
|
||||
let prevDiff = pipeStart.elevation - groundAt(pipeStart.offset);
|
||||
for (let t = 0.02; t <= 3; t += 0.02) {
|
||||
const px = pipeStart.offset + axis.offset * t;
|
||||
const pe = pipeStart.elevation + axis.elevation * t;
|
||||
const diff = pe - groundAt(px);
|
||||
if (Math.abs(diff) < 0.005 || Math.sign(diff) !== Math.sign(prevDiff)) {
|
||||
endFaces.inlet = {
|
||||
base: { offset: px, elevation: pe },
|
||||
direction: endFaces.inlet.direction,
|
||||
};
|
||||
break;
|
||||
}
|
||||
prevDiff = diff;
|
||||
}
|
||||
}
|
||||
const endCorners = (role: "inlet" | "outlet", endPoint: OffsetPoint): PipeEnd => {
|
||||
const fallback: PipeEnd = {
|
||||
bottom: endPoint,
|
||||
@@ -600,6 +577,11 @@ export function computeCulvertLayout(
|
||||
: 0;
|
||||
}
|
||||
|
||||
// I형 집수정: 관 하단 꼭짓점이 지반 위에 뜨면 수평 되메움선(Basin 분리 — 700줄).
|
||||
if (basin) {
|
||||
applyBasinPipeFill(basin, pipeCorners.inlet.bottom, inletInfo.outward, groundAt);
|
||||
}
|
||||
|
||||
// 보호공(돌붙임) — 유출측. 2026-08-20 사용자 ①·②:
|
||||
// ① 시작 변은 **기슭막이 전면과 같은 경사**(밑면을 벽 전면 방향으로 민다),
|
||||
// 윗면 시작점 = **관 하단 꼭짓점**(관 밑면과 한 점에서 만난다).
|
||||
|
||||
Reference in New Issue
Block a user