fix(abut-rebar): 벽체 W9 · W10 구간별 ⊓형 (양끝 다리 l_d)

- 사용자 도면(2026-11-04): 구간마다 독립된 ⊓, 양끝 계단 경계 − c (끝면 쪽은 W11 안쪽)에서 아래로 다리 l_d 735
- 낮은 이웃 구간으로의 직선 연장과 RB-AB06 피복 경고 삭제
- 계단 단면 삽도 · 안내 문구 반영

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-11-04 16:45:20 +09:00
1 parent 34959f5b4e
commit 74de932eb9
4 files changed
+25 -29

No files matched your search

+13 -15
View File
@@ -81,15 +81,19 @@ describe('교대 벽체 배근 A1 (AD4, 교대벽체철근.md §11)', () => {
expect(bar(abutWallRebar(withSegs(4), footing, undefined, fck27), 'W10').count).toBe(12);
});
it('W9 extends l_d 735 into the lower neighbour only', () => {
const k = 2; // a middle step, neighbours on both sides
it('W9 · W10: ⊓ per step, ends at the boundary − 100 (끝면 쪽은 W11 안쪽), legs down l_d 735 (사용자 도면 2026-11-04)', () => {
const k = 2; // a middle step
const sg = geom.segments[k];
const z = 1100 + sg.H - 100 - 15.9;
const p = A1.paths.find((q) => q.mark === 'W10' && Math.abs(q.pts[0][2] - z) < 1e-6)!;
const lowLeft = geom.segments[k - 1].H < sg.H;
const lowRight = geom.segments[k + 1].H < sg.H;
expect(p.pts[0][0]).toBeCloseTo(lowLeft ? sg.from - 735 : sg.from, 6);
expect(p.pts[1][0]).toBeCloseTo(lowRight ? sg.to + 735 : sg.to, 6);
const p = A1.paths.find((q) => q.mark === 'W10' && Math.abs(q.pts[1][2] - z) < 1e-6)!;
expect(p.pts.map((q) => Math.round(q[0] * 10) / 10)).toEqual([sg.from + 100, sg.from + 100, sg.to - 100, sg.to - 100].map((v) => Math.round(v * 10) / 10));
expect(p.pts[0][2]).toBeCloseTo(z - 735, 6);
expect(p.pts[3][2]).toBeCloseTo(z - 735, 6);
const w = A1.bars.find((b) => b.mark === 'W10')!;
expect(w.length).toBe(Math.round(sg.to - sg.from - 200 + 2 * 735));
// 끝 계단: 끝면 쪽은 W11 안쪽 (100 + (15.9 + 15.9)/2) / sin θ.
const w9 = A1.paths.find((q) => q.mark === 'W9')!;
expect(w9.pts[1][0]).toBeCloseTo((100 + 15.9) / angle.sin, 6);
});
it('W7: 12 × 5 = 60, 2200 / sin θ + 2 × 197 = 2603 (skew, 사용자 결정 2026-11-04)', () => {
@@ -113,14 +117,8 @@ describe('교대 벽체 배근 A1 (AD4, 교대벽체철근.md §11)', () => {
expect(xs).toEqual([-700, -400, -100, ...Array.from({ length: 13 }, (_, i) => i * 125)]);
});
it('A1 warns only RB-AB06: W9 · W10 연장부 피복 44.9 < 100 (계단 71.1)', () => {
expect(A1.issues.filter((i) => i.level !== 'I').map((i) => i.code)).toEqual(['RB-AB06']);
expect(A1.issues.find((i) => i.code === 'RB-AB06')!.message).toContain('44.9');
});
it('RB-AB06 is gone when the steps are flat enough (높이 차 0)', () => {
const flat = { ...geom, segments: geom.segments.map((s) => ({ ...s, H: 2372 })) };
expect(abutWallRebar(flat, footing, undefined, fck27).issues.map((i) => i.code)).not.toContain('RB-AB06');
it('A1 has no warning (RB-AB02 · RB-AB03 없음, W9 · W10은 이웃 구간으로 넘어가지 않음)', () => {
expect(A1.issues.filter((i) => i.level !== 'I').map((i) => i.code)).toEqual([]);
});
it('l_d 연동: fck 30 → W2 앞 다리 · W3 위 끝이 짧아짐', () => {