fix(abut): 교대 받침 공통 규칙을 교각 솔플레이트 규칙 형식으로 변경

- 이전 가정(받침 A×B 700×640, h3 181, T 30, 여유 100)을 없애고, 교각과 같은 솔플레이트 규칙(src/core/solplate-rule.ts)을 씀 (결정 2026-11-03: 교각 규칙을 기본값으로)
- 입력: 솔플레이트 교직 L 1000, 교축 W 1100, 종단 기울기 S −0.5 %. 받침높이 H는 교대 받침 시트 값(A1 275 mm)으로 고정
- 계산: T = ⌈22 + L·|S|/200⌉ = 25, h3 = H − T = 250, T1 27.5 / T2 22.5, E = 400. 교각 카드와 같은 안내 줄 표시
- 받침 종류 · 용량 입력은 유지. ELEVATION TABLE의 A·B 열 삭제, 삽도는 솔플레이트 L × W 기준
- 테스트 갱신. 전체 651건 통과, 타입 검사·빌드 통과. 브라우저 시각 확인은 미실시

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Opus 5.5 committed 2026-11-03 18:37:17 +09:00
1 parent 4b02dde153
commit 6b969f4a7c
7 files changed
+137 -110

No files matched your search

+28 -15
View File
@@ -18,6 +18,7 @@ import {
ABUT_PAD_PLAN_MM,
abutBearingChecks,
abutElevationRows,
abutSolplatePlan,
abutSolplateRows,
resolveBearingRule,
} from './core/abut/bearing-table';
@@ -68,7 +69,7 @@ import { columnDiameterIssues } from './core/column-check';
import { findPileSpec, PHC_PILES, STEEL_PILES } from './core/pile-spec';
import { footingPlanSvg, footingSideSvg } from './view/footing-svg';
import { P1_COPING_GEOM } from './core/coping-geom';
import { SOLPLATE_RULE_DEFAULT, solplatePlan, solplateRuleIssues } from './core/solplate-rule';
import { SOLPLATE_MIN_T2_MM, SOLPLATE_RULE_DEFAULT, solplatePlan, solplateRuleIssues } from './core/solplate-rule';
import type { SolplateRule } from './core/types';
import { type BarSummary, elevationRows, solplateRows } from './core/bearing-table';
@@ -805,8 +806,10 @@ function fillAbutBearingCard(
return;
}
const m3 = (v: number) => v.toFixed(3);
const elev = abutElevationRows(model, rule);
const sol = abutSolplateRows(model, rule, rec.slopeI);
const H = rec.bearingHeightMm;
const plan = abutSolplatePlan(rule, H);
const elev = abutElevationRows(model, rule, H);
const sol = abutSolplateRows(model, rule, H);
// 상세 보기 (받침 ①–⑤): the three 삽도 draw the picked bearing.
const pickNo = elev.some((r) => r.no === state.abutBearingNo) ? state.abutBearingNo : elev[0].no;
const picker = el('div', undefined, 'abut-bearing-pick');
@@ -825,14 +828,14 @@ function fillAbutBearingCard(
const er = elev.find((r) => r.no === pickNo)!;
const sr = sol.find((r) => r.no === pickNo)!;
const detail: AbutBearingDetail = {
no: er.no, blockMm: ABUT_BLOCK_MM, padMm: ABUT_PAD_PLAN_MM, A: er.A, B: er.B, L: sr.L, W: sr.W,
no: er.no, blockMm: ABUT_BLOCK_MM, padMm: ABUT_PAD_PLAN_MM, L: sr.L, W: sr.W,
h1: er.h1, h2: er.h2, h3: er.h3, h4: er.h4, T1: sr.T1, T2: sr.T2, rotDeg: er.rotDeg, S: sr.S, seatEl: er.seatEl, z: er.z,
};
const figs = el('div', undefined, 'abut-bearing-figs');
for (const [svg, caption] of [
[abutBearingPlanSvg(detail), '평면 · 점선 = 몰탈패드, 주황 점선 = 솔플레이트'],
[abutBearingPlanSvg(detail), '평면 · 점선 = 몰탈패드, 주황 = 솔플레이트 L × W'],
[abutBearingSectionSvg(detail), '단면 · 교축 방향 · E = h1 + h2 + h3 + h4'],
[abutSolplateSvg(detail), '솔플레이트 상세 · 가정'],
[abutSolplateSvg(detail), '솔플레이트 상세 · T = ⌈22 + L·|S|/200⌉'],
]) {
const fig = el('figure', undefined, 'abut-fig');
fig.innerHTML = svg;
@@ -840,26 +843,28 @@ function fillAbutBearingCard(
figs.append(fig);
}
box.append(figs);
box.append(el('p', '받침 ELEVATION TABLE (mm, EL·위치는 m) · 거리는 IP3(① 쪽)에서 · h3·h4는 가정 (QA-15)', 'lbl'));
box.append(el('p', `받침 ELEVATION TABLE (mm, EL·위치는 m) · 거리는 IP3(① 쪽)에서 · h3 = H − T, h4 = T (솔플레이트 규칙)`, 'lbl'));
box.append(
table(
['No.', '위치 s', '구간', '교좌면 EL', 'h1 블럭', 'h2 패드', 'z = EL.X', 'h3 받침', 'h4 솔플', 'E', '솔플 상면 EL', 'A', 'B', '블럭 ~ 계단 경계', '방위각 CAD / 진북 (°)', '블럭 회전 (°)'],
['No.', '위치 s', '구간', '교좌면 EL', 'h1 블럭', 'h2 패드', 'z = EL.X', 'h3 받침', 'h4 솔플', 'E', '솔플 상면 EL', '블럭 ~ 계단 경계', '방위각 CAD / 진북 (°)', '블럭 회전 (°)'],
elev.map((r) => [
String(r.no), m3(r.sFromIp3M), r.seg, m3(r.seatEl), String(r.h1), String(r.h2), m3(r.z), String(r.h3), String(r.h4),
String(r.E), m3(r.solplateTopEl), String(r.A), String(r.B), r.stepGapM === null ? '—' : m3(r.stepGapM),
String(r.E), m3(r.solplateTopEl), r.stepGapM === null ? '—' : m3(r.stepGapM),
r.azimuthCadDeg === null || r.azimuthNorthDeg === null ? '입력 없음' : `${r.azimuthCadDeg.toFixed(3)} / ${r.azimuthNorthDeg.toFixed(3)}`,
r.rotDeg.toFixed(2),
]),
),
);
box.append(el('p', '솔플레이트 상세 TABLE (mm) · 가정 (교각 P1 값)', 'lbl'));
box.append(el('p', '솔플레이트 상세 TABLE (mm) · 솔플레이트 규칙', 'lbl'));
box.append(
table(
['No.', 'S (%)', 'L', 'W', 'T', 'T1', 'T2', '검산 T1 − T2 ≈ L·|S|'],
sol.map((r) => [String(r.no), r.S.toFixed(3), String(r.L), String(r.W), String(r.T), String(r.T1), String(r.T2), r.check]),
['No.', 'S (%)', 'L', 'W', 'T', 'T1', 'T2', '검산 T1 − T2 = L·|S|/100'],
sol.map((r) => [String(r.no), r.S.toFixed(3), String(r.L), String(r.W), String(r.T), r.T1.toFixed(1), r.T2.toFixed(1), r.check]),
),
);
box.append(el('p', `공통 · 규칙 — 블럭 평면 ${ABUT_BLOCK_MM} × ${ABUT_BLOCK_MM} (기본값) · 몰탈패드 ${ABUT_PAD_PLAN_MM} × ${ABUT_PAD_PLAN_MM} × 50 (기본값) · 블럭 높이 = min(z) − 교좌면 (계산)`, 'muted small'));
// 솔플레이트 규칙 (교각 카드와 같은 형식, 2026-11-03): H는 교대 받침 시트 값으로 고정, L · W · S를 입력한다.
const d = ABUT_BEARING_RULE_DEFAULT;
box.append(el('p', `솔플레이트 규칙 (이 교대 · 기본 ${d.lengthMm} × ${d.widthMm} · ${d.slopePct} %) · 받침높이 H ${H} mm 고정 (솔플레이트 포함)`, 'lbl'));
for (const f of BEARING_RULE_FIELDS) {
const id = idOf(`rule-${f.key}`);
const lab = el('label', f.label);
@@ -873,8 +878,16 @@ function fillAbutBearingCard(
fail(err, input, String(rule[f.key]));
}
});
box.append(lab, input, el('span', `기본 ${ABUT_BEARING_RULE_DEFAULT[f.key]} · 가정`, 'muted small'));
box.append(lab, input, el('span', `기본 ${ABUT_BEARING_RULE_DEFAULT[f.key]}`, 'muted small'));
}
box.append(
el(
'p',
`중심 두께 T = ${plan.T} mm (T2 ≥ ${SOLPLATE_MIN_T2_MM} mm) · 받침 본체 h3 = H − T = ${plan.h3} mm · T1 = ${plan.T1.toFixed(1)} mm · T2 = ${plan.T2.toFixed(1)} mm`,
'muted small',
),
);
box.append(el('p', `블럭 평면 ${ABUT_BLOCK_MM} × ${ABUT_BLOCK_MM} (기본값) · 몰탈패드 ${ABUT_PAD_PLAN_MM} × ${ABUT_PAD_PLAN_MM} × 50 (기본값) · 블럭 높이 = min(z) − 교좌면 (계산)`, 'muted small'));
const kindId = idOf('rule-kind');
const kindLab = el('label', '받침 종류 · 용량');
kindLab.htmlFor = kindId;
@@ -890,7 +903,7 @@ function fillAbutBearingCard(
}
});
box.append(kindLab, kind, el('span', `기본 ${ABUT_BEARING_RULE_DEFAULT.kind}`, 'muted small'));
box.append(el('p', `검사 · ${abutBearingChecks(model, members, rule).join(' · ')}`, 'muted small abut-checks'));
box.append(el('p', `검사 · ${abutBearingChecks(model, members, rule, H).join(' · ')}`, 'muted small abut-checks'));
}
/** Shows only the card of the open row in the ② 교대 editor; the basic items stay visible. */