fix(평면): 벽 측점 비탈 끝 윤곽에 벽 윗면 · 앞면 그대로 — 3D 벽 도형 땅 만남과 0 차 (PLAN 578-2)

- 성토 위 이음 → 전면 발끝 대각선 대신 벽 도형 앞 위 → 앞 밑(buildRevetWallGeometry 차례) · 이음 안쪽 0.1 m 만큼 갈리던 것

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 13:31:03 +09:00
co-authored by Claude Opus 5.5
parent bfa2b3a97f
commit ee49754b46
@@ -196,7 +196,7 @@ function fordPipeLengthM(ford: FordLayout): number | null {
}
/** 벽(옹벽 · 흙막이 · 돌쌓기)이 선 쪽 — 구조물 처리 뒤 횡단이 땅과 만나는 오프셋(578-2).
* 윤곽 = 트림 사면(노견 → 벽 이음) → 단마다 벽 앞(성토 위 이음 → 전면 발끝) · 사이 성토부선(3D 실루엣 차례).
* 윤곽 = 트림 사면(노견 → 벽 이음) → 단마다 벽 윗면 · 앞면(→ 전면 발끝) · 사이 성토부선(3D 실루엣 차례).
* 위에서 내려와 처음 땅에 닿는 자리 · 끝까지 안 닿으면(뜬 벽) 마지막 발끝 · 노견부터 땅 밑이면 null. */
function wallSlopeEnd(section: CrossSection, own: RevetmentLayout): number | null {
const groundAt = groundInterpolator(section.samples);
@@ -204,7 +204,8 @@ function wallSlopeEnd(section: CrossSection, own: RevetmentLayout): number | nul
const chain = [...((own.side === "left" ? trim.maxSlope : trim.minSlope)?.points ?? [])];
const segments = own.fillSegments.filter((segment) => segment.kind !== "cut");
own.walls.forEach((wall, index) => {
chain.push(wall.fillTop, wall.bottomFront, ...(segments[index]?.points ?? []));
// 벽 도형 = [뒤 밑, 뒤 위, 앞 위, 앞 밑](`buildRevetWallGeometry`) — 앞면이 그려지는 모양 그대로
chain.push(wall.fillTop, ...wall.points.slice(2), ...(segments[index]?.points ?? []));
});
if (!groundAt || chain.length < 2) return null;
let [prev, above] = [chain[0], chain[0].elevation - groundAt(chain[0].offset)];