Files
Pier_v1/tests/rebar-stairs.test.ts
ypshimandClaude Haiku 5.5 72053be420 feat(rebar): C15·C16 폭 간격을 2 × 주철근 기본간격에 연동
- stairBars가 pitch를 받는다 (기본 2 × 기본간격 = 250, P1 그대로)
- 3D와 철근표가 같은 pitch를 쓴다
- 철근표 간격·실간격: 2 × 기본간격, 근거는 기본값/입력

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-26 16:04:31 +09:00

77 lines
3.3 KiB
TypeScript
Raw Permalink 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 { buildPier } from '../src/core/geometry';
import { c14Bars, c14Length, copingSideBars, stairBars, undersideAt } from '../src/core/rebar/coping';
import { loadP1 } from './helpers';
const m = buildPier(loadP1());
const L = m.copingL * 1000;
const B = m.copingB * 1000;
const side = copingSideBars(L, 41.288, 42.538);
const rows = [...side.c12, ...side.c13];
const under = (x: number) => undersideAt(L, x, m.endBottom, m.levelBottom);
describe('C14 / C15 / C16 (코핑철근.md §7–8)', () => {
it('C14: 2 upper lines of 11 (C2, C3) and lower rows 5 / 6 / 3 / 2 = 38', () => {
const bars = c14Bars(L, m.copingRefTop, rows, under);
const count = (line: number) => bars.filter((b) => b.line === line).length;
expect(count(1)).toBe(11);
expect(count(2)).toBe(11);
expect([3, 4, 5, 6].map(count)).toEqual([5, 6, 3, 2]);
expect(bars.length).toBe(38);
});
it('C14 heights: upper 43.208 / 43.108, lower 42.810 / 42.310 / 41.810 / 41.310 (상면 단 간격 100)', () => {
const bars = c14Bars(L, m.copingRefTop, rows, under);
const z = (line: number) => bars.find((b) => b.line === line)!.z;
expect(z(1)).toBeCloseTo(43.208, 3);
expect(z(2)).toBeCloseTo(43.108, 3);
expect([3, 4, 5, 6].map(z)).toEqual([42.81, 42.31, 41.81, 41.31].map((v) => expect.closeTo(v, 2)));
});
it('C14 length 3447.5 (2855.5 run + 2 × 296 legs)', () => {
expect(c14Length(B)).toBeCloseTo(3447.5, 0);
});
it('C15: 11 bars, z 43.598, length 3852 (2088 + 2 × 882)', () => {
const { c15 } = stairBars(L, B, m.copingRefTop);
expect(c15.length).toBe(11);
expect(c15[0].z).toBeCloseTo(43.598, 3);
expect(c15[0].length).toBeCloseTo(3852, 0);
expect(c15[0].x0).toBeCloseTo(9812, 0);
});
it('C16: 22 bars (3·4구간), z 43.436 / 43.507, lengths 4070 / 4069', () => {
const { c16 } = stairBars(L, B, m.copingRefTop);
expect(c16.length).toBe(22);
expect(c16[0].z).toBeCloseTo(43.436, 3);
expect(c16[11].z).toBeCloseTo(43.507, 3);
expect(c16[0].length).toBeCloseTo(4070, 0);
expect(c16[11].length).toBeCloseTo(4069, 0);
});
it('C15 / C16 across positions: 137 from the cover line, then @250, 11 bars', () => {
const { c15 } = stairBars(L, B, m.copingRefTop);
expect(c15[0].n).toBeCloseTo(-B / 2 + 237, 0);
expect(c15[10].n - c15[0].n).toBeCloseTo(2500, 0);
});
});
describe('C14 연직 발 (코핑철근.md §8)', () => {
it('upper lines keep their legs; a lower bar keeps its legs only if they end above the underside', () => {
const bars = c14Bars(L, m.copingRefTop, rows, under);
expect(bars.filter((b) => b.line <= 2).every((b) => b.legs)).toBe(true);
// The leg of the C12 5단 bar (line 4) at the ends (x 1 m, 11 m) would end below the sloped underside, so it is left out.
const omitted = bars.filter((b) => !b.legs).map((b) => [b.line, Math.round(b.x / 1000)]);
expect(omitted).toEqual([[4, 1], [4, 11]]);
});
});
describe('C15 간격 = 2 × 주철근 기본간격 (승인 2026-10-26)', () => {
it('the default pitch is 250, and a larger pitch moves the 11 C15 bars apart', () => {
const { c15 } = stairBars(L, B, m.copingRefTop);
expect(c15[1].n - c15[0].n).toBe(250);
const wider = stairBars(L, B, m.copingRefTop, undefined, 280).c15;
expect(wider[1].n - wider[0].n).toBe(280);
});
});