feat(B06): 횡단도 안 조정창 = 제목 · 단추만 · 그림 끌기 두 축 함께 + 놓을 때 패널 걸음 맞춤 · 미리 보기 = 맞춘 자리(108-1 · 108-2)
- 조정창(오버레이): 읽기 줄 · 줄 이름 · 머리줄 집수정 ↺ 지움 · 끄는 중 미리 보기 글만 · 좌측 사본 그대로 - 끌기: 벽 · 집수정 · 세월교 = 수평 + 1:1.2 사면 · 다단 · 독립 벽 = 수평 + 수직 · BOX = 길이 + 표고 - 한계(±10 m · 노견 안쪽 · 노면 위 · 다단 선반 · BOX 길이 0)면 가장 가까운 허용 자리 · 반영 한 번 - 시험 test_108_drag_box_hit(끌기 · 걸음 · 미리 보기 = placePipeWall 결과 · 한계 · BOX 판정면) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
This commit is contained in:
@@ -8,10 +8,13 @@
|
||||
import type { CrossSection } from "./B06_Section_Api_Fetch";
|
||||
import type { RevetKey } from "./B06_Section_UI_Cross_Culvert";
|
||||
import {
|
||||
FILL_SLOPE_RATIO_MIN,
|
||||
PIPE_WALL_DEFAULT_RUN_M,
|
||||
REVET_EMBED_DEPTH_M,
|
||||
REVET_FORM_DEFAULT,
|
||||
WALL_MIN_PURE_HEIGHT_M,
|
||||
} from "./B06_Section_UI_Cross_Culvert_Const";
|
||||
import { clampAxis, type AxisDragSpec } from "./B06_Section_UI_Cross_Panel_Base";
|
||||
import type { CulvertLayout } from "./B06_Section_UI_Cross_Culvert_Types";
|
||||
import type { WallAdjust } from "./B06_Section_UI_Cross_Culvert_Types";
|
||||
import type { StructurePanelDeps } from "./B06_Section_UI_Cross_Structure_Panel";
|
||||
@@ -149,6 +152,7 @@ export function structurePanelDeps(ctx: StructurePanelContext): StructurePanelDe
|
||||
// 배관/독립 종속 추가 벽·옛 D경로 독립 벽)는 0.1m. 세월교 흙막이는 안이 관이라 1m(80).
|
||||
fineMove: (key) =>
|
||||
(key !== "inlet" && key !== "outlet") || (ctx.hiddenPipe() && !ctx.fordGuard?.()),
|
||||
dragAxes: (key, basin) => wallDragAxes(ctx, key, basin),
|
||||
extraState: () => ctx.extraState(),
|
||||
isLinkedCard: () => ctx.isLinked,
|
||||
basinExtraState: () => ctx.basinExtraState(),
|
||||
@@ -222,6 +226,70 @@ export function structurePanelDeps(ctx: StructurePanelContext): StructurePanelDe
|
||||
};
|
||||
}
|
||||
|
||||
/** 끌기 한계 ±10 m — 제어기 `clampMove`(`_Page_Station_Controls`)와 같다. */
|
||||
const DRAG_LIMIT_M = 10;
|
||||
const round1 = (value: number): number => Math.round(value * 10) / 10;
|
||||
|
||||
/**
|
||||
* 벽 · 집수정 그림 끌기 두 축(108-2) — 축 뜻 · 한계 · 한 번 반영. 한계는 저장 · 기하가 거는 것 중
|
||||
* 미리 알 수 있는 것(±10 m · 안쪽 금지 · 노면 위 금지 · 다단 선반 1.2·d) — 넘으면 가장 가까운 허용 자리.
|
||||
* · 배관 기준벽 · 집수정 = ▲▼ 1:1.2 사면(`placePipeWall` · `_Culvert_Basin` 사면 이동)
|
||||
* · 다단 · 독립 벽 = ▲▼ 순수 수직(`_Culvert_Extra` · `_Revetment` 축)
|
||||
*/
|
||||
function wallDragAxes(
|
||||
ctx: StructurePanelContext,
|
||||
key: RevetKey,
|
||||
basin: boolean,
|
||||
): Omit<AxisDragSpec, "stepM"> | null {
|
||||
if (!ctx.revetOffset) return null;
|
||||
const outward = ctx.outwardOf(basin ? "inlet" : key);
|
||||
if (basin) {
|
||||
const from = ctx.inletStructure?.adjustFor(ctx.section);
|
||||
if (!from) return null;
|
||||
const lateralMove = (left: number): number =>
|
||||
clampAxis(from.lateralM, left * outward, 0, DRAG_LIMIT_M);
|
||||
return {
|
||||
slopeOutward: outward,
|
||||
clamp: (left, down) => [
|
||||
lateralMove(left) * outward,
|
||||
clampAxis(from.slopeM, down, 0, DRAG_LIMIT_M),
|
||||
],
|
||||
apply: (left, down) =>
|
||||
ctx.inletStructure?.updateAdjust(ctx.adjustChainage(), {
|
||||
...from,
|
||||
lateralM: round1(from.lateralM + left * outward),
|
||||
slopeM: round1(from.slopeM + down),
|
||||
}),
|
||||
};
|
||||
}
|
||||
const adjust = ctx.adjustOf(key);
|
||||
const d0 = adjust.d ?? ctx.appliedD().get(key) ?? 0;
|
||||
const diagonal = key === "inlet" || key === "outlet";
|
||||
// x 하한 — 배관 기준벽 = 안쪽 금지(흙막이는 본체 끝이 0점이라 안 막음 · 73-4) · 다단 = 선반 ≥ 0 ·
|
||||
// 독립 = 성토선 각도(1.2·d − 기본 run)
|
||||
const xLow = (d: number): number =>
|
||||
isTierKey(key)
|
||||
? Math.max(0, FILL_SLOPE_RATIO_MIN * d)
|
||||
: key === "own"
|
||||
? FILL_SLOPE_RATIO_MIN * d - PIPE_WALL_DEFAULT_RUN_M
|
||||
: ctx.bodyGuard?.()
|
||||
? -DRAG_LIMIT_M
|
||||
: 0;
|
||||
return {
|
||||
slopeOutward: diagonal ? outward : null,
|
||||
clamp: (left, down) => {
|
||||
const dMove = clampAxis(d0, down, 0, DRAG_LIMIT_M);
|
||||
const low = Math.max(xLow(d0 + dMove), -DRAG_LIMIT_M);
|
||||
return [clampAxis(adjust.x, left * outward, low, DRAG_LIMIT_M) * outward, dMove];
|
||||
},
|
||||
apply: (left, down) =>
|
||||
ctx.revetOffset?.update(ctx.adjustChainage(), key, {
|
||||
x: round1(adjust.x + left * outward),
|
||||
d: round1(d0 + down),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 조정창이 쓸 **카드 상태**를 마지막 기하 결과에서 뽑는다(2026-08-25 분리 — 카드
|
||||
* 렌더러 700줄). 값 계산은 하지 않고 레이아웃 결과를 조정창 키 체계로 옮기기만 한다.
|
||||
|
||||
Reference in New Issue
Block a user