Files
Pier_v1/tests/rebar-footing.test.ts
T
ypshimandClaude Haiku 5.5 99db6a1f52 Revert "feat(rebar): B1–B4와 B5–B8 방향 교환 (B1–B4는 W 방향, B5–B8은 L 방향)"
이 교환은 9,350 방향이 L이라는 가정에서 적용됐으나, 단면 삽도(B5–B8 선, 교각축 직각 단면)와 재료표가 원래 배치(B1–B4 L 방향, B5–B8 W 방향)와 맞는 것으로 확인되어 되돌림.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-27 09:48:05 +09:00

137 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import { assemblyBars, bottomBars, crossBars, grid, layers, legB2, shearB9, sideBars } from '../src/core/rebar/footing';
// P1 footing: L 10400 × W 8150 × H 2000.
const L = 10400;
const W = 8150;
const H = 2000;
describe('확대기초 철근 (확대기초철근 (1).md, plan C5)', () => {
it('grid across W: n 61, G 7625, e 162.5, 62 positions (§3.3)', () => {
const g = grid(W);
expect(g.n).toBe(61);
expect(g.G).toBe(7625);
expect(g.e).toBeCloseTo(162.5, 6);
expect(g.positions).toBe(62);
});
it('배근도 재현 grid: W 7800 → n 58, e 175', () => {
const g = grid(7800);
expect(g.n).toBe(58);
expect(g.e).toBeCloseTo(175, 6);
});
it('layer heights: B5 1900, B1 1873, B2·B4 150, B6·B8 177, B3 250, B7 277', () => {
const z = layers(H);
expect(z.B5).toBe(1900);
expect(z.B1).toBeCloseTo(1873, 6);
expect(z.B24).toBe(150);
expect(z.B68).toBeCloseTo(177, 6);
expect(z.B3).toBe(250);
expect(z.B7).toBeCloseTo(277, 6);
});
it('B2 leg 1723, B2 length 13646 (over the 12000 bar, splice needed)', () => {
expect(legB2(H)).toBeCloseTo(1723, 6);
const b2 = bottomBars(L, W, H).find((b) => b.name === 'B2')!;
expect(b2.length).toBeCloseTo(13646, 0);
expect(b2.count).toBe(31);
});
it('B1–B4 counts 31 / 31 / 31 / 31 and B4 length 10200', () => {
const bars = bottomBars(L, W, H);
expect(bars.map((b) => b.count)).toEqual([31, 31, 31, 31]);
expect(bars.find((b) => b.name === 'B4')!.length).toBeCloseTo(10200, 6);
});
it('B5–B8 counts 40 each (grid along L: n 79), B8 length 7950, B6 length 11396', () => {
const bars = crossBars(L, W, H);
expect(bars.map((b) => b.count)).toEqual([40, 40, 40, 40]);
expect(bars.find((b) => b.name === 'B8')!.length).toBeCloseTo(7950, 6);
expect(bars.find((b) => b.name === 'B6')!.length).toBeCloseTo(11396, 0);
});
it('B10-1 16 bars ≈ 10748 (lowest level removed), B10-2 16 bars ≈ 8494', () => {
const [b101, b102] = sideBars(L, W, H);
expect(b101.count).toBe(16);
expect(b101.length).toBeCloseTo(10748, 0);
expect(b102.count).toBe(16);
expect(b102.length).toBeCloseTo(8494, 0);
});
it('B10 levels from the height: H 2000 → m 8 (9 levels), H 2200 → m 9 (10 levels), as in the document', () => {
expect(b10Levels(2000)).toBe(9);
expect(b10Levels(2200)).toBe(10);
expect(assemblyJs(2000)).toEqual([2, 4, 6]);
expect(assemblyJs(2200)).toEqual([2, 4, 6, 8]);
});
// k = 8 default (승인 2026-10-26): every 8 grid steps (1000 mm). The doc's 4s (k = 4) gives 60 / 47.
it('B11 30 bars (10 / 10 / 10) ≈ 8359, B12 24 bars (8 / 8 / 8) ≈ 10613 at k = 8', () => {
const [b11, b12] = assemblyBars(L, W, H);
expect(b11.count).toBe(30);
expect(b11.length).toBeCloseTo(8359, 0);
expect(b12.count).toBe(24);
expect(b12.length).toBeCloseTo(10612.5, 1); // the document prints ≈ 10613
});
it('B9 shear: 16 rows, 20 per row on the grid, 320 in all, length ≈ 2128 (l_v 1750 + 2 × 189)', () => {
const b9 = shearB9(L, W, H, []);
expect(b9.rows).toBe(16);
expect(b9.perRow.every((c) => c === 20)).toBe(true);
expect(b9.count).toBe(320);
expect(b9.length).toBeCloseTo(2128, 0);
});
it('B9 column zone: bars whose centre is within D/2 + d/2 of a column axis are left out (P1: 14 bars)', () => {
const b9 = shearB9(L, W, H, [0], 2000);
expect(b9.count).toBe(306);
for (const b of b9.bars) expect(Math.hypot(b.x, b.n)).toBeGreaterThan(1000 + 7.95);
});
});
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', () => {
const o = legOffsets();
expect(o.B1).toBeCloseTo(25.4, 6);
expect(o.B3).toBeCloseTo(22.25, 6);
expect(o.B5).toBeCloseTo(28.6, 6);
expect(o.B7).toBeCloseTo(23.85, 6);
});
it('B11 at 550 / 950 / 1350 and B12 at 569.1 / 969.1 / 1369.1', () => {
const h = assemblyHeights(H);
expect(h.B11).toEqual([550, 950, 1350]);
expect(h.B12.map((z) => Math.round(z * 10) / 10)).toEqual([569.1, 969.1, 1369.1]);
});
it('배근도 재현 W 7800 → B4 30, B2 29 (odd count split)', () => {
const bars = bottomBars(10400, 7800, 2000);
expect(bars.find((b) => b.name === 'B4')!.count).toBe(30);
expect(bars.find((b) => b.name === 'B2')!.count).toBe(29);
});
it('배근도 재현 L 9350 → B8 36, B6 35', () => {
const bars = crossBars(9350, 8150, 2000);
expect(bars.find((b) => b.name === 'B8')!.count).toBe(36);
expect(bars.find((b) => b.name === 'B6')!.count).toBe(35);
});
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, { ...DEFAULT_FOOTING_REBAR, sAxis: 150 });
expect(g.n).toBe(50);
expect(g.e).toBeCloseTo(150, 6);
expect(grid(12000).n).toBe(92);
expect(grid(12000).e).toBeCloseTo(150, 6);
});
it('splice cases: L 8700 → B2 11946 (no splice); L 12400 → B4 12200; W 8800 → B6 12046', () => {
expect(bottomBars(8700, 8150, 2000).find((b) => b.name === 'B2')!.length).toBeCloseTo(11946, 0);
expect(bottomBars(12400, 8150, 2000).find((b) => b.name === 'B4')!.length).toBeCloseTo(12200, 0);
expect(crossBars(10400, 8800, 2000).find((b) => b.name === 'B6')!.length).toBeCloseTo(12046, 0);
});
});