feat(core): B9 shear bars of the footing (plan C5)

- B9 (확대기초철근 (1).md §9): H16 with the 135° stirrup hook, on the odd grid
  (i_W = 1, 5, …), 16 rows, 20 per row (even rows start at i_L 1, odd at 3),
  320 bars, length l_v 1750 + 2 × 189 ≈ 2128.
- The rebar summary now lists B9; the alert about B9 is gone. Positions and
  hooks are the document's proposed rules (Q-B18, Q-B19), noted on the row.
- Tests: the document's B9 values; P1 summary has 320 and only the splice alert.
- Not verified in a browser.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-22 11:34:56 +09:00
1 parent 3af8729e9f
commit 73bff19aba
4 files changed
+35 -6

No files matched your search

+20
View File
@@ -145,3 +145,23 @@ export function assemblyBars(L: number, W: number): FootingBar[] {
{ name: 'B12', size: 'S16', count: b12, length: L - 2 * 139.75 + 2 * hook },
];
}
/**
* B9 전단철근 (확대기초철근 (1).md §9). Wraps B5 (top outer) and B2·B4 (bottom outer), H16 @500 staggered.
* Plane positions and hooks are proposed rules (Q-B18, Q-B19).
*/
export function shearB9(L: number, W: number, H: number): { rows: number; perRow: number[]; count: number; length: number } {
const nW = grid(W).n; // 61
const nL = grid(L).n; // 79
const rowIndices: number[] = [];
for (let i = 1; i <= nW; i += 4) rowIndices.push(i);
// Even-numbered rows start at i_L = 1, odd-numbered rows at i_L = 3 (2s stagger).
const perRow = rowIndices.map((_, r) => {
const start = r % 2 === 0 ? 1 : 3;
return Math.floor((nL - start) / 4) + 1;
});
const count = perRow.reduce((a, b) => a + b, 0);
const lv = layers(H).B5 - layers(H).B24; // 1750
const lh = hookLength('stirrup135', d('H16'));
return { rows: rowIndices.length, perRow, count, length: lv + 2 * lh };
}
+3 -3
View File
@@ -3,7 +3,7 @@ import { bearingBlockRebar, totals } from './bearing-block';
import { bottomPiece, topBarLength, widthLayout } from './coping-main';
import { shearBars, sideRows, C14_COUNTS, c14Total, STEP_BAR_COUNTS } from './coping';
import { columnRebar, COLUMN_P1 } from './column';
import { bottomBars, crossBars, sideBars, assemblyBars } from './footing';
import { bottomBars, crossBars, sideBars, assemblyBars, shearB9 } from './footing';
/** One line of a 철근표. length is null where the document gives no length yet. */
export interface RebarRow {
@@ -89,8 +89,8 @@ export function rebarSummary(model: PierModel): { rows: RebarRow[]; warnings: Re
}
for (const b of sideBars(Lf, Wf)) rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '측면 수평' });
for (const b of assemblyBars(Lf, Wf)) rows.push({ member: 'footing', name: b.name, size: b.size, count: b.count, length: b.length, note: '조립 수평' });
rows.push({ member: 'footing', name: 'B9', size: 'H16', count: 0, length: null, note: '전단철근 미계산' });
warnings.push({ code: 'RB-F09', message: 'B9 (전단철근)은 아직 계산하지 않았습니다.' });
const b9 = shearB9(Lf, Wf, Hf);
rows.push({ member: 'footing', name: 'B9', size: 'H16', count: b9.count, length: b9.length, note: `전단 @500 엇갈림, ${b9.rows}행 (위치·갈고리는 Q-B18·B19 제안)` });
} else {
warnings.push({ code: 'RB-F00', message: '현장타설말뚝은 확대기초가 없어 확대기초 철근을 만들지 않습니다.' });
}