- 받침마다 1개 블럭 (1200 × 1200, 높이 125 − 패드 50 = 콘크리트 75). 본수 · 다리 · 여유는 교각 규칙(barsAcross · barLength) 재사용, 깊이만 교대 H13으로 계산 - 묻힘 S2 675 · S1 688, 길이 2500, 블럭당 8본 (40 · 40). 블럭 방위각 회전 - 간섭 (Q-S4, 결정 2026-11-05): S1 다리가 W2 층을 지나면 RB-AK01 경고만 - 테스트: 교대 기획서 §10 값, 간섭 경고, 간격 수정, 회전 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
53 lines
2.6 KiB
TypeScript
53 lines
2.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { abutBlockRebar, abutBarDepths } from '../src/core/abut/rebar/block';
|
||
|
||
// 교대 받침블럭 (교대 기획서 §10 · 받침블럭철근.md §6.6): 블럭 5개, 1200 × 1200, 높이 125 (패드 50 포함, 콘크리트 75).
|
||
const blocks = [1, 2, 3, 4, 5].map((no, i) => ({ no, s: 1 + i * 2, t: 0.2, rotDeg: 0, seatEl: 44.367, blockHeightMm: 125 }));
|
||
const bottom = 40.895;
|
||
const A1 = abutBlockRebar(blocks, bottom);
|
||
const bar = (r: typeof A1, m: 'S1' | 'S2') => r.bars.find((b) => b.mark === m)!;
|
||
|
||
describe('교대 받침블럭 배근 A1 (AD6, 교대 기획서 §10)', () => {
|
||
it('블럭 콘크리트 75 (블럭 125 − 패드 50), 깊이: S2 50 · S1 62.7 (H13 두 개)', () => {
|
||
expect(A1.concreteH).toBe(75);
|
||
expect(abutBarDepths(A1.settings)).toEqual({ S2: 50, S1: 50 + 6.35 + 6.35 });
|
||
});
|
||
|
||
it('본수: 블럭마다 8본 (7@125, 끝 162.5), 5개 → S1 40 · S2 40', () => {
|
||
expect(bar(A1, 'S1').count).toBe(40);
|
||
expect(bar(A1, 'S2').count).toBe(40);
|
||
expect(A1.paths.filter((p) => p.mark === 'S1' && p.block === 1).length).toBe(8);
|
||
// 블럭 1 (s = 1000 mm): S2 본은 블럭 모서리에서 162.5, 125 간격 → 첫 본 s = 1000 − 600 + 162.5 = 562.5.
|
||
const s2 = A1.paths.filter((p) => p.mark === 'S2' && p.block === 1).map((p) => p.pts[0][0]).sort((a, b) => a - b);
|
||
expect(s2[0]).toBeCloseTo(562.5, 6);
|
||
expect(s2[1] - s2[0]).toBeCloseTo(125, 6);
|
||
expect(s2.length).toBe(8);
|
||
});
|
||
|
||
it('길이 2500 (1100 직선 + 다리 700 × 2), 묻힘: S2 675 · S1 688', () => {
|
||
expect([bar(A1, 'S1').length, bar(A1, 'S2').length]).toEqual([2500, 2500]);
|
||
expect(Math.round(A1.embedment.S2)).toBe(675);
|
||
expect(Math.round(A1.embedment.S1)).toBe(688);
|
||
});
|
||
|
||
it('간섭 (Q-S4, 경고만): S1 다리가 W2 층을 지남 → RB-AK01 (W), 다른 오류 없음', () => {
|
||
const codes = A1.issues.map((i) => `${i.code}:${i.level}`);
|
||
expect(codes).toContain('RB-AK01:W');
|
||
expect(A1.issues.filter((i) => i.level === 'E')).toEqual([]);
|
||
});
|
||
|
||
it('간격 수정 → RB-AK03 "수정됨"', () => {
|
||
const r = abutBlockRebar(blocks, bottom, { spacingS1: 150 });
|
||
expect(r.issues.map((i) => i.code)).toContain('RB-AK03');
|
||
expect(bar(r, 'S1').modified).toBe(true);
|
||
expect(bar(r, 'S2').modified).toBe(false);
|
||
});
|
||
|
||
it('회전 (방위각): 블럭 축이 돌면 경로 점도 같이 돈다 (교대축 방향 길이 보존)', () => {
|
||
const r = abutBlockRebar([{ ...blocks[0], rotDeg: 30 }], bottom);
|
||
const p = r.paths.find((q) => q.mark === 'S1')!;
|
||
const len = Math.hypot(p.pts[2][0] - p.pts[1][0], p.pts[2][1] - p.pts[1][1]);
|
||
expect(len).toBeCloseTo(1100, 6);
|
||
});
|
||
});
|