feat(core): rebar common rules (plan C1) and bearing-block bars (plan C2)
- C1: development length l_d = 0.6·d_b·fy/(λ√fck), splice 1.3·l_d, standard hooks (main 90°, tie 90°, stirrup 135° as written in the spec). fck 27 and fy 400/500 are marked as assumed values (I02). - C2: bearing-block bars, one block per bearing (배치 분리). Bars S1 and S2 at @125 with 8 bars per 1200 mm side (7 gaps = 875, ends 162.5), 2500 mm long, coping embedment from the block height (pad included, Q16 결정). - Tests: development and splice lengths; hook table limits; embedment 600 / 550 / 619.1 / 569.1; P1 has 80 bars each of S1 and S2 over 10 blocks. - Not yet: the ③ screen and the drawing check against the bearing-block drawing. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e297db1251
commit
daf78d0586
4 files changed
+189
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import type { PierModel } from '../geometry';
|
||||
|
||||
/**
|
||||
* 받침블럭 철근 (spec §6.3 · plan C2), 배치 분리: one block per bearing, 1200 × 1200.
|
||||
* S2 is the upper bar (cover 50 from the block top); S1 is the lower bar (69.1 below the top).
|
||||
* Both have the same layout: 7@125 = 875 with ends of 162.5 in a 1200 mm block, and legs of 700 below the bar.
|
||||
*/
|
||||
export const BLOCK_REBAR = {
|
||||
dim: 1200,
|
||||
cover: 50,
|
||||
firstBarGap: 75,
|
||||
spacing: 125,
|
||||
/** Straight part of the bar for the 1200 block (spec table: 1100 + 700 × 2). */
|
||||
straight: 1100,
|
||||
legLength: 700,
|
||||
/** Depth of each bar centre below the block top (mm). */
|
||||
depthS2: 50,
|
||||
depthS1: 69.1,
|
||||
} as const;
|
||||
|
||||
export interface BarRow {
|
||||
name: 'S1' | 'S2';
|
||||
/** Bars along one block side. */
|
||||
count: number;
|
||||
spacing: number;
|
||||
/** Position of the first bar from the block edge. */
|
||||
firstEnd: number;
|
||||
/** Straight length plus two legs (mm). */
|
||||
length: number;
|
||||
/** Coping embedment of the legs (mm): 700 − (block height − bar depth). */
|
||||
embedment: number;
|
||||
}
|
||||
|
||||
/** Bars along one 1200 mm side: available = dim − 2·(cover + first gap); gaps = floor(available / spacing). */
|
||||
export function barsAcross(dim = BLOCK_REBAR.dim): { count: number; spacing: number; firstEnd: number } {
|
||||
const available = dim - 2 * (BLOCK_REBAR.cover + BLOCK_REBAR.firstBarGap);
|
||||
const gaps = Math.floor(available / BLOCK_REBAR.spacing);
|
||||
const span = gaps * BLOCK_REBAR.spacing;
|
||||
const leftover = available - span;
|
||||
return { count: gaps + 1, spacing: BLOCK_REBAR.spacing, firstEnd: BLOCK_REBAR.cover + BLOCK_REBAR.firstBarGap + leftover / 2 };
|
||||
}
|
||||
|
||||
/** Rebar of one block; blockHeight is the bearing block height in mm (h1 front or h2 back, pad included). */
|
||||
export function blockBars(blockHeight: number, dim = BLOCK_REBAR.dim): BarRow[] {
|
||||
const across = barsAcross(dim);
|
||||
const length = BLOCK_REBAR.straight + 2 * BLOCK_REBAR.legLength;
|
||||
return [
|
||||
{ name: 'S1', ...across, length, embedment: BLOCK_REBAR.legLength - (blockHeight - BLOCK_REBAR.depthS1) },
|
||||
{ name: 'S2', ...across, length, embedment: BLOCK_REBAR.legLength - (blockHeight - BLOCK_REBAR.depthS2) },
|
||||
];
|
||||
}
|
||||
|
||||
export interface BlockRebar {
|
||||
no: number;
|
||||
row: '전열' | '후열';
|
||||
bars: BarRow[];
|
||||
}
|
||||
|
||||
/** Rebar of every block of a pier, using the model's block heights (h1 front, h2 back; pad included, Q16 결정). */
|
||||
export function bearingBlockRebar(model: PierModel): BlockRebar[] {
|
||||
return model.blocks.map((b) => ({
|
||||
no: b.no,
|
||||
row: b.row,
|
||||
bars: blockBars(b.row === '전열' ? model.h1 * 1000 : model.h2 * 1000),
|
||||
}));
|
||||
}
|
||||
|
||||
/** Total bars of one pier: bars per block × blocks, for S1 and S2 separately. */
|
||||
export function totals(rebar: BlockRebar[]): { S1: number; S2: number } {
|
||||
return rebar.reduce(
|
||||
(sum, blk) => {
|
||||
for (const bar of blk.bars) sum[bar.name] += bar.count;
|
||||
return sum;
|
||||
},
|
||||
{ S1: 0, S2: 0 },
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* ③ 철근배근 공통 규칙 (spec §6.2 · plan C1). Lengths in mm, stresses in MPa.
|
||||
* fck and fy are inputs. The defaults below are assumed values and must be shown as such (I02).
|
||||
*/
|
||||
export const MATERIAL_DEFAULTS = {
|
||||
fck: 27,
|
||||
/** H = SD400, S = SD500. */
|
||||
fy: { H: 400, S: 500 } as const,
|
||||
/** 경량 콘크리트 계수 λ (보통 콘크리트 1.0). */
|
||||
lambda: 1.0,
|
||||
/** Marks that these are assumed values (정보 I02). */
|
||||
assumed: true,
|
||||
} as const;
|
||||
|
||||
/** Development length l_d = 0.6·d_b·f_y / (λ·√f_ck) (spec §4 공통 설계 규약, 보정계수 1.0). */
|
||||
export function developmentLength(db: number, fy: number, fck: number, lambda = MATERIAL_DEFAULTS.lambda): number {
|
||||
if (db <= 0 || fy <= 0 || fck <= 0 || lambda <= 0) throw new Error('정착길이 계산 값은 모두 0보다 커야 합니다.');
|
||||
return (0.6 * db * fy) / (lambda * Math.sqrt(fck));
|
||||
}
|
||||
|
||||
/** Lap splice length l_s = 1.3·l_d (spec §4 공통 설계 규약). */
|
||||
export function spliceLength(db: number, fy: number, fck: number, lambda = MATERIAL_DEFAULTS.lambda): number {
|
||||
return 1.3 * developmentLength(db, fy, fck, lambda);
|
||||
}
|
||||
|
||||
export type HookKind = 'main90' | 'tie90' | 'stirrup135';
|
||||
|
||||
/**
|
||||
* Standard hook lengths (KDS 14 20 52, spec §4). Refuses bar sizes outside the table rather than guessing.
|
||||
* - main90: 주철근 90°, D25 이하 15.5 d_b, D29–D35 16.5 d_b
|
||||
* - tie90: 띠철근 90°, D16 이하 8.5 d_b
|
||||
* - stirrup135: 스터럽 135°, 2.5·d_b·(3π/4) + 6·d_b (spec formula, as written)
|
||||
*/
|
||||
export function hookLength(kind: HookKind, db: number): number {
|
||||
if (kind === 'main90') {
|
||||
if (db <= 25) return 15.5 * db;
|
||||
if (db <= 35) return 16.5 * db;
|
||||
throw new Error(`주철근 90° 갈고리 표에 없는 지름입니다 (D${db}).`);
|
||||
}
|
||||
if (kind === 'tie90') {
|
||||
if (db <= 16) return 8.5 * db;
|
||||
throw new Error(`띠철근 90° 갈고리 표에 없는 지름입니다 (D${db}).`);
|
||||
}
|
||||
return 2.5 * db * ((3 * Math.PI) / 4) + 6 * db;
|
||||
}
|
||||
Reference in new issue
Block a user