feat(rebar): 조립 철근(B11·B12)을 격자 가운데에 배치 (양끝 여유 차이 ≤ 1칸)

- assemblyGridIndices: 단마다 k칸 간격, 엇갈림 2칸 유지, 짝수 단 시작칸을 가운데 정렬
- 개수는 그대로 (B11 30, B12 24), 3D와 단면 삽도가 같은 위치를 씀
- 테스트: 양끝 여유 차이 ≤ 1칸, 엇갈림 2칸

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-26 17:47:21 +09:00
1 parent 20d8546b6f
commit de20b84c00
4 files changed
+34 -16

No files matched your search

+12 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { buildPier } from '../src/core/geometry';
import { assemblyBars, assemblyJs, b9Bars, bottomBars, crossBars, sideBars } from '../src/core/rebar/footing';
import { assemblyBars, assemblyGridIndices, assemblyJs, b9Bars, bottomBars, crossBars, sideBars } from '../src/core/rebar/footing';
import { DEFAULT_FOOTING_REBAR } from '../src/core/rebar/footing-settings';
import { footingSectionSvg } from '../src/view/footing-section-svg';
import { loadP1 } from './helpers';
@@ -38,4 +38,15 @@ describe('확대기초 교각축 직각 단면 (폭 W) (승인 2026-10-26, 추
it('has one bubble per highlighted bar family', () => {
for (const name of ['B1', 'B2', 'B3', 'B4', 'B5', 'B11', 'B10-1']) expect(svg).toContain(`data-bubble="${name}"`);
});
it('조립 철근은 격자 가운데에 놓임: 양끝 여유 차이 ≤ 1칸 (B11 n 79, B12 n 61, k 8, 엇갈림 2칸 유지)', () => {
const levels = assemblyJs(H, fs).length;
for (const [n, k] of [[79, 8], [61, 8]] as const) {
const all = Array.from({ length: levels }, (_, idx) => assemblyGridIndices(n, k, idx)).flat();
const left = Math.min(...all);
const right = n - Math.max(...all);
expect(Math.abs(left - right)).toBeLessThanOrEqual(1);
}
expect(assemblyGridIndices(61, 8, 1)[0] - assemblyGridIndices(61, 8, 0)[0]).toBe(2);
});
});