fix(b06): 암 절토 입력을 1:n 으로 바꾸고 기슭막이 대각선 제거·조정창 자리 내림
암 절토 칸은 속값이 이미 경사비인데 화면만 각도(°)로 바꿔 보여 줘, 도면·좌측 표준 설정·품셈이 모두 1:n 인 자리에서 이 칸만 머리로 환산해야 했음. 머리말 「1:」과 n 입력으로 바꿈. 기슭막이 상단에서 바닥으로 늘 긋던 대각 이음선은 사용자 지시로 뺌. 조정창이 좌측 상단 면적표를 덮어 수치가 안 보이던 것을 표 높이만큼 내려 세움. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fe1QWPTfw11PaKh2LjwXdR
This commit is contained in:
@@ -6,8 +6,9 @@
|
||||
* 좌측 패널의 표준 횡단면 설정을 이용」. 그래서 **전체 기본값은 좌측 패널**, **이 칸은 그 측점
|
||||
* 하나**만 바꾼다. 표준을 바꿔도 여기서 만진 측점은 그대로다(사용자 값이라 재계산이 살려 둔다).
|
||||
*
|
||||
* 화면에는 **각도(°)**로 보이고 속으로는 경사비(1:n 의 n)로 다닌다 — 소단 폼의
|
||||
* 「안쪽 기울기 (°)」와 같은 말법이다. 1:0.4 = 68.2° · 1:1.0 = 45° · 1:1.5 = 33.7°.
|
||||
* 화면도 속도 **경사비(1:n 의 n)** 로 쓴다(2026-09-12 사용자 지시). 종전에는 화면만 각도(°)로
|
||||
* 바꿔 보여 줬는데, 도면·좌측 [표준 횡단면 설정]·품셈이 모두 1:n 이라 이 칸만 머리로 환산해야
|
||||
* 했다. 참고: 1:0.4 = 68.2° · 1:1.0 = 45° · 1:1.5 = 33.7°.
|
||||
*
|
||||
* ⚠ 경사는 **나르는 값이 아니라 기하 입력**이다. 계산이 끝난 결과에 값만 베껴 붙이면 설계선은
|
||||
* 옛 경사로 그려지고 숫자만 새것이 된다 — 값은 반드시 **계산 전에** 넘어가야 한다
|
||||
@@ -37,13 +38,18 @@ export function degreesToRatio(degrees: number): number {
|
||||
return 1 / Math.tan((clamped * Math.PI) / 180);
|
||||
}
|
||||
|
||||
/** 0.1° 단위로 같은 값인가 — 표준값으로 되돌아왔는지 가리는 데 쓴다. */
|
||||
function sameDegrees(a: number, b: number): boolean {
|
||||
return Math.abs(a - b) < 0.05;
|
||||
/** 경사비를 화면 자릿수(0.01)로 맞춘다 — 사면이 서지 않는 각도(1~89° 밖)는 잘라 받는다. */
|
||||
export function clampRatio(ratio: number): number {
|
||||
return Math.round(degreesToRatio(ratioToDegrees(ratio)) * 100) / 100;
|
||||
}
|
||||
|
||||
/** 0.01 단위로 같은 값인가 — 표준값으로 되돌아왔는지 가리는 데 쓴다. */
|
||||
function sameRatio(a: number, b: number): boolean {
|
||||
return Math.abs(a - b) < 0.005;
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드 하단에 서는 「암 절토 68.2° ↺」 칸. 암 경계선 제어와 같은 자리·같은 모양이다.
|
||||
* 카드 하단에 서는 「암 절토 1:0.40 ↺」 칸. 암 경계선 제어와 같은 자리·같은 모양이다.
|
||||
*
|
||||
* 되돌리기(↺)는 **표준 횡단면 설정값**으로 돌려놓는다 — 좌측 패널을 그 뒤에 바꾸면 이 측점도
|
||||
* 따라간다(사용자가 만진 흔적이 지워지므로).
|
||||
@@ -58,30 +64,34 @@ export function buildCutSlopeControl(section: CrossSection, control: CutSlopeCon
|
||||
|
||||
const group = document.createElement("div");
|
||||
group.className = "b06-design__seg-buttons";
|
||||
const ratio = control.ratioFor(section);
|
||||
const standard = control.standardRatioFor(section);
|
||||
const degrees = ratioToDegrees(ratio);
|
||||
const ratio = clampRatio(control.ratioFor(section));
|
||||
const standard = clampRatio(control.standardRatioFor(section));
|
||||
|
||||
// 「1:」은 고정 머리말 — 사용자가 넣는 것은 뒤의 n 하나다.
|
||||
const prefix = document.createElement("span");
|
||||
prefix.className = "b06-design__cutslope-unit";
|
||||
prefix.textContent = "1:";
|
||||
|
||||
const input = document.createElement("input");
|
||||
input.type = "number";
|
||||
input.className = "b06-design__cutslope-input";
|
||||
input.step = "0.5";
|
||||
input.min = "1";
|
||||
input.max = "89";
|
||||
input.value = degrees.toFixed(1);
|
||||
input.step = "0.05";
|
||||
input.min = "0.02";
|
||||
input.max = "57.29";
|
||||
input.value = ratio.toFixed(2);
|
||||
input.title =
|
||||
`이 측점의 암 절토 경사 — 각도(°)로 넣는다.\n` +
|
||||
`지금 1:${ratio.toFixed(2)} (${degrees.toFixed(1)}°) · 표준 1:${standard.toFixed(2)} (${ratioToDegrees(standard).toFixed(1)}°)\n` +
|
||||
`이 측점의 암 절토 경사 — 경사비(1:n 의 n)로 넣는다. n 이 작을수록 급하다.\n` +
|
||||
`지금 1:${ratio.toFixed(2)} (${ratioToDegrees(ratio).toFixed(1)}°) · 표준 1:${standard.toFixed(2)} (${ratioToDegrees(standard).toFixed(1)}°)\n` +
|
||||
`전체를 바꾸려면 좌측 [표준 횡단면 설정]을 쓴다.`;
|
||||
const commit = (): void => {
|
||||
const entered = Number(input.value);
|
||||
if (!Number.isFinite(entered)) {
|
||||
input.value = degrees.toFixed(1);
|
||||
if (!Number.isFinite(entered) || entered <= 0) {
|
||||
input.value = ratio.toFixed(2);
|
||||
return;
|
||||
}
|
||||
// 표준값으로 되돌아온 입력은 사용자 값을 남기지 않는다 — 그래야 표준을 바꿀 때 따라간다.
|
||||
const next = sameDegrees(entered, ratioToDegrees(standard)) ? null : degreesToRatio(entered);
|
||||
control.set(section.chainage_m, next);
|
||||
const next = clampRatio(entered);
|
||||
control.set(section.chainage_m, sameRatio(next, standard) ? null : next);
|
||||
};
|
||||
input.addEventListener("change", commit);
|
||||
input.addEventListener("keydown", (event) => {
|
||||
@@ -93,22 +103,18 @@ export function buildCutSlopeControl(section: CrossSection, control: CutSlopeCon
|
||||
// 카드 클릭(선택·줌)이 입력을 뺏지 않게 한다 — 암 경계선 버튼과 같은 태도.
|
||||
input.addEventListener("pointerdown", (event) => event.stopPropagation());
|
||||
|
||||
const unit = document.createElement("span");
|
||||
unit.className = "b06-design__cutslope-unit";
|
||||
unit.textContent = "°";
|
||||
|
||||
const reset = document.createElement("button");
|
||||
reset.type = "button";
|
||||
reset.className = "b06-design__rockb-btn is-reset";
|
||||
reset.textContent = "↺";
|
||||
reset.title = `표준값으로 되돌리기 (1:${standard.toFixed(2)} · ${ratioToDegrees(standard).toFixed(1)}°)`;
|
||||
reset.disabled = sameDegrees(degrees, ratioToDegrees(standard));
|
||||
reset.disabled = sameRatio(ratio, standard);
|
||||
reset.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
control.set(section.chainage_m, null);
|
||||
});
|
||||
|
||||
group.append(input, unit, reset);
|
||||
group.append(prefix, input, reset);
|
||||
wrap.append(group);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
@@ -172,15 +172,9 @@ export function appendWallHatch(
|
||||
((offset - wall.bottomBack.offset) / bottomSpan)
|
||||
: wall.bottomBack.elevation;
|
||||
|
||||
// 평행사변형 띠와 사다리꼴 사이 대각 이음선(사용자 스케치의 가운데 선) —
|
||||
// 상단 변 중간점에서 전면과 나란히 바닥으로 내려온다. 형태와 무관하게 늘 긋는다.
|
||||
const jointBaseOffset = wall.outerOffset - wall.outward * REVET_THICKNESS_M;
|
||||
layer.append(
|
||||
line(
|
||||
[x(wall.topJoint.offset), toDisplayY(wall.topJoint.elevation)],
|
||||
[x(jointBaseOffset), toDisplayY(bottomAtOffset(jointBaseOffset))],
|
||||
),
|
||||
);
|
||||
// 벽을 가로지르던 대각 이음선은 **긋지 않는다**(2026-09-12 사용자: 필요 없음).
|
||||
// 종전에는 상단 변 중간점에서 바닥까지 형태와 무관하게 늘 그어, 돌쌓기·콘크리트 해칭
|
||||
// 위로 선이 하나 더 지나가 도면이 지저분했다.
|
||||
|
||||
clipSeq += 1;
|
||||
const clipId = `b06-revet-clip-${keyId}-${clipSeq}`;
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
* 넘칠 만큼 길어지면 창 안에서 스크롤한다. z-index는 카드 안 오버레이 중 최상단. */
|
||||
.b06-structure-panel {
|
||||
position: absolute;
|
||||
top: var(--spacing-8);
|
||||
/* 좌측 상단에는 절·성토 면적표가 이미 서 있다 — 조정창을 같은 자리에 두면 표를 덮어
|
||||
수치가 안 보인다(2026-09-12 사용자). 표 높이(머리글+절토+성토 세 줄)만큼 내려 시작한다.
|
||||
아래를 기준으로 붙이지 않는 까닭은 종전 그대로다 — 낮은 횡단도에서 창이 잘린다. */
|
||||
top: calc(var(--spacing-8) + var(--b06-areas-height, 3.2rem));
|
||||
left: var(--spacing-8);
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
max-height: calc(100% - 2 * var(--spacing-8));
|
||||
max-height: calc(100% - 2 * var(--spacing-8) - var(--b06-areas-height, 3.2rem));
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: var(--spacing-8);
|
||||
|
||||
Reference in New Issue
Block a user