feat(rebar): 확대기초 배근 입력 8개 (피복 3·여유·격자 s·s_v·e_top·n), FT01·FT02 검사
- core/rebar/footing-settings.ts: 입력 정의, 기본값(확대기초철근 (1).md), 범위(제안), 검사 (FT01 범위, FT02 n 정수) - 확대기초 계산 함수가 설정을 인자로 받음 (기본값 = 기존 값, 기존 호출은 그대로) - 3D 확대기초 그림의 125·100 하드코딩 제거, 철근표·3D·기둥 층 높이가 같은 설정을 씀 - 패널: 상면·측면·하면 피복을 칸 분리, s_v와 e_top 분리. 고정 규칙(k=2, Δ₂=100, 전단 4s·엇갈림 2s, cycle 교대)과 B2·B6 디리는 읽기 전용으로 표시 - 기본값에서 P1 결과 불변 (기존 테스트 통과) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
550b508e7a
commit
5a20a18185
11 files changed
+281
-96
No files matched your search
@@ -0,0 +1,39 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildPier } from '../src/core/geometry';
|
||||
import { assemblyJs, gridPositions } from '../src/core/rebar/footing';
|
||||
import { DEFAULT_FOOTING_REBAR, FOOTING_REBAR_RANGES, footingSettingsIssues } from '../src/core/rebar/footing-settings';
|
||||
import { rebarSummary } from '../src/core/rebar/summary';
|
||||
import { loadP1 } from './helpers';
|
||||
|
||||
describe('확대기초 배근 입력 (승인 2026-10-26, 시안 ③ 확대기초)', () => {
|
||||
it('the defaults are inside every range and raise no issue', () => {
|
||||
expect(footingSettingsIssues(DEFAULT_FOOTING_REBAR)).toEqual([]);
|
||||
for (const [key, [lo, hi]] of Object.entries(FOOTING_REBAR_RANGES)) {
|
||||
const v = DEFAULT_FOOTING_REBAR[key as keyof typeof DEFAULT_FOOTING_REBAR];
|
||||
expect(v >= lo && v <= hi, key).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it('a value outside its range gives FT01; a non-integer n gives FT02', () => {
|
||||
expect(footingSettingsIssues({ ...DEFAULT_FOOTING_REBAR, cTop: 151 })).toEqual([expect.objectContaining({ code: 'FT01', key: 'cTop' })]);
|
||||
expect(footingSettingsIssues({ ...DEFAULT_FOOTING_REBAR, n: 2.5 })).toEqual([expect.objectContaining({ code: 'FT02', key: 'n' })]);
|
||||
});
|
||||
|
||||
it('the grid spacing s reaches the grid positions and the rebar table', () => {
|
||||
const m = buildPier({ ...loadP1(), footingRebar: { s: 150 } });
|
||||
expect(m.footingRebar.s).toBe(150);
|
||||
const xs = gridPositions(8000, m.footingRebar);
|
||||
expect(xs[1] - xs[0]).toBeCloseTo(150, 6);
|
||||
const b4 = rebarSummary(m).rows.find((r) => r.name === 'B4')!;
|
||||
const b4Default = rebarSummary(buildPier(loadP1())).rows.find((r) => r.name === 'B4')!;
|
||||
expect(b4.count).not.toBe(b4Default.count);
|
||||
});
|
||||
|
||||
it('the 조립 단 배수 n reaches the assembly levels', () => {
|
||||
const H = 2000;
|
||||
const base = assemblyJs(H, DEFAULT_FOOTING_REBAR);
|
||||
const wider = assemblyJs(H, { ...DEFAULT_FOOTING_REBAR, n: 3 });
|
||||
expect(wider.length).toBeLessThan(base.length);
|
||||
expect(wider.every((j) => j % 3 === 0)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -90,6 +90,7 @@ describe('확대기초 철근 (확대기초철근 (1).md, plan C5)', () => {
|
||||
});
|
||||
|
||||
import { assemblyHeights, assemblyJs, b10Levels, legOffsets } from '../src/core/rebar/footing';
|
||||
import { DEFAULT_FOOTING_REBAR } from '../src/core/rebar/footing-settings';
|
||||
|
||||
describe('확대기초 배근도 재현 (확대기초철근 (1).md §13)', () => {
|
||||
it('leg offsets: B1 +25.4, B3 +22.25, B5 +28.6, B7 +23.85', () => {
|
||||
@@ -119,7 +120,7 @@ describe('확대기초 배근도 재현 (확대기초철근 (1).md §13)', () =>
|
||||
});
|
||||
|
||||
it('variables: W 8000 with s 150 → 50 grid steps, e 150, B4 26 / B2 25; W 12000 → 92 steps, e 150', () => {
|
||||
const g = grid(8000, 150);
|
||||
const g = grid(8000, { ...DEFAULT_FOOTING_REBAR, s: 150 });
|
||||
expect(g.n).toBe(50);
|
||||
expect(g.e).toBeCloseTo(150, 6);
|
||||
expect(grid(12000).n).toBe(92);
|
||||
|
||||
Reference in new issue
Block a user