fix(B06): 독립 기슭막이에도 좌우 이동 안내 + 하한 알림 조건 좁힘

- 독립 기슭막이(D군) 툴팁은 **따로 만들어져** 있어 「지형에 막힘」조차 안 떴음.
  배관 벽과 같은 두 줄(지형 막힘 · 각도 하한)을 같은 문구로 붙임.
- 기준벽 경로(`computeRevetmentLayout`)에도 `shiftFloorM` 을 남김 —
  하한이 `1.2 × 상하 내림 − 자동 자리`라 d 2.6m 자리에서 1.0m 요청이 삼켜졌음.
- 하한 알림은 **사용자가 실제로 값을 넣었을 때만** 뜨게 좁힘. 요청이 0이면
  하한은 그냥 기본 자리라 모든 벽에 뜨면 소리만 됨.
- 문구를 두 경로에 맞게 고침 — 「상하 내림의 1.2배」가 아니라
  「성토선 각도(1:1.2)를 지키려면 그만큼은 나가 있어야 함」.
- 시험 3건(`test_b06_extra_shift_floor.py`) — 하한 적용·알림·요청 없을 때 침묵.

미확인 — 실화면에서 알림이 뜨는 것까지는 못 봄. 지금 프로젝트(용화)의 카드가
전부 링크 카드라 좌우 이동 조작 자체가 먹지 않아 조건을 세우지 못했음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 10:02:03 +09:00
co-authored by Claude Opus 5
parent ec153bc2e8
commit 023c0d545a
3 changed files with 25 additions and 4 deletions
+3 -2
View File
@@ -12,6 +12,7 @@
import {
REVET_EMBED_DEPTH_M,
FILL_SLOPE_RATIO_MIN,
REVET_LEAN_RATIO,
pipeWallThicknessM,
revetHeightLimit,
@@ -181,8 +182,8 @@ export function appendCulvertOverlay(
? ` · ⚠ 좌우 이동 ${wall.shiftBlockedM.toFixed(2)}m 는 지형에 막힘(더 나가면 벽이 묻힘)`
: "") +
(wall.shiftFloorM
? ` · ⚠ 좌우 이동 하한 ${wall.shiftFloorM.toFixed(2)}m — 상하 내림의 1.2배까지는` +
` 따라 나가야 함(그보다 안쪽은 선반이 사라짐). 그 아래 넣으면 안 움직임`
? ` · ⚠ 좌우 이동 하한 ${wall.shiftFloorM.toFixed(2)}m — 성토선 각도(1:${FILL_SLOPE_RATIO_MIN})를` +
` 지키려면 그만큼은 나가 있어야 함. 그 아래 값을 넣으면 벽이 안 움직임`
: ""),
);
if (onSelectRevet) revetShape.classList.add("is-selectable");
@@ -445,8 +445,12 @@ export function buildOutletExtras(input: OutletExtrasInput): OutletExtrasResult
if (blocked > 0.005) wall.shiftBlockedM = Math.round(blocked * 100) / 100;
// 하한에 눌려 요청이 통째로 무시된 경우 — 지형이 아니라 **선반 길이**가 원인이다
// (2026-09-07 실측: d 2.6m 이면 x 하한이 3.12m 라 1.0m 요청이 아무 변화도 못 냄).
// 사용자가 실제로 넣었을 때만 알린다 — 요청이 없으면(0) 하한은 그냥 기본 자리라
// 알릴 것이 없다(모든 벽에 뜨면 소리만 됨).
const floor = shelfFloor(appliedD);
if (floor > (requestedX ?? 0) + 0.005) wall.shiftFloorM = Math.round(floor * 100) / 100;
if ((requestedX ?? 0) > 0.005 && floor > (requestedX ?? 0) + 0.005) {
wall.shiftFloorM = Math.round(floor * 100) / 100;
}
walls.push(wall);
// 되받기 — 지반에 맞춰 조정한 값이 **실제 적용 높이**다(조정창이 그대로 받아 적는다).
appliedAdjusts.push({
+17 -1
View File
@@ -240,6 +240,13 @@ export function computeRevetmentLayout(
lengthM,
floatGapM,
});
// 넣은 좌우 이동이 **각도 하한**에 눌려 통째로 무시됐으면 그 하한을 남긴다(2026-09-07).
// 실측 — d 2.6m 자리에서 하한이 1.0m 를 넘어 「1.0m 를 넣어도 0.00m 이동」이 났고,
// 지형에 막힌 것이 아니라 `shiftBlockedM` 은 0 이어서 까닭을 알 길이 없었다.
const floorNow = xFloor(appliedDrop);
if (requestedX > 0.005 && floorNow > requestedX + 0.005) {
tier1.shiftFloorM = Math.round(floorNow * 100) / 100;
}
// 다단 — 배관과 같은 함수. 1단 벽 전면 하단 꼭짓점을 성토부선 시작점으로.
const requestedTiers = Math.max(1, Math.round(Number(spec.tiers) || 1));
@@ -363,7 +370,16 @@ export function appendRevetmentOverlay(
(wall.floatGapM > 0.01
? ` · ⚠ 바닥 원지반 이격 ${wall.floatGapM.toFixed(2)}m — 하부 지지 별도`
: ` · 근입 ${REVET_EMBED_DEPTH_M.toFixed(2)}m`) +
(wall.lengthM ? ` · 연장 ${wall.lengthM.toFixed(1)}m` : "");
(wall.lengthM ? ` · 연장 ${wall.lengthM.toFixed(1)}m` : "") +
// 「좌우로 옮겨도 안 움직인다」의 까닭 두 가지 — 배관 벽 툴팁과 같은 문구다
// (2026-09-07). 독립 벽 툴팁은 따로 만들어져 있어 여태 어느 쪽도 안 떴다.
(wall.shiftBlockedM
? ` · ⚠ 좌우 이동 ${wall.shiftBlockedM.toFixed(2)}m 는 지형에 막힘(더 나가면 벽이 묻힘)`
: "") +
(wall.shiftFloorM
? ` · ⚠ 좌우 이동 하한 ${wall.shiftFloorM.toFixed(2)}m — 성토선 각도(1:${FILL_SLOPE_RATIO_MIN})를` +
` 지키려면 그만큼은 나가 있어야 함. 그 아래 값을 넣으면 벽이 안 움직임`
: "");
const shape = drawRevetWall(svg, wall, x, y, "b06-chart__culvert-revet", tooltip, keyId);
if (onSelect) shape.classList.add("is-selectable");
drawn.push(shape);