feat(core): bearing-block drawing check and coping rebar C3 (plan C2·C3)

- Drawing check (spec §6.3): an integrated 2500 × 1200 block gives 18@125 = 2250
  along (ends 50 + 75) and 7@125 = 875 across (ends 162.5).
- C3 coping rebar, from RAG/코핑철근.md (2026-10-22 final):
  - C10: 9 bars @300 at 4800–7200 (k_max 4, beyond the Level edge).
  - C9 / C11: 18 bars each @250 outward, ends at 300 and 11700 (end gap 300).
  - Refuses a coping too short for C9 (RB-K01).
  - Side bars C12 5 rows / C13 2 rows at the 42.538 break; C14 38 bars;
    C15 11 bars, C16 22 bars.
- spec §6.4 is older than 코핑철근.md (C10/C9/C11 layout, C12 row count, C14
  dimensions). This follows the final document; spec §6.4 needs an update.
- Not yet: C1–C8 main bars (shape and lengths), the C12/C13 bar lengths and
  shapes, the drawing check of the coping sheet, and the ③ screen.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-22 11:08:27 +09:00
1 parent daf78d0586
commit b962cf1a1c
4 files changed
+143 -2

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
/**
* 코핑 철근 (plan C3). Source: RAG/코핑철근.md, 2026-10-22 최종 정리 (spec §6.4 is older and is not used here).
* Positions are along the coping length from its start, in mm.
*/
export const COPING_REBAR = {
/** 피복 (최외측 철근 중심까지). */
cover: 100,
/** 첫 전단철근 최소 여유 e_add. 끝 여유 e_min = cover + e_add = 300. */
eAdd: 200,
/** Level 폭 W_L. */
levelWidth: 2100,
/** C10 간격 s_L (기둥 중심부터). */
spacingL: 300,
/** C9·C11 간격 s_s (C10에서 바깥으로). */
spacingS: 250,
/** C12·C13 측면 수평 간격. */
spacingSide: 250,
/** C14 위 2줄 간격 / 아래 줄 수평 간격 / 아래 줄 연직 간격 / 끝 여유. */
c14: { upperSpacing: 1000, lowerSpacing: 2000, verticalSpacing: 500, endGap: 500 },
} as const;
export const COPING_END_GAP = COPING_REBAR.cover + COPING_REBAR.eAdd;
export interface ShearBars {
/** C10 positions (mm), from the first to the last. */
c10: number[];
/** C9 positions (mm), from the left end toward the column. */
c9: number[];
/** C11 positions (mm), from the column toward the right end. */
c11: number[];
/** Distance from the coping end to the outermost C9 / C11 bar (mm). */
endGap: number;
}
/**
* Shear bars C9–C11 along the axis (코핑철근.md §3). A single column at the coping centre.
* C10: @300 from the column centre, out to the first position beyond the Level edge (k_max).
* C9 / C11: @250 outward from the outermost C10, as many as fit with the end gap of at least 300.
*/
export function shearBars(coping: number, xc = coping / 2): ShearBars {
const { spacingL, spacingS, levelWidth } = COPING_REBAR;
const kMax = Math.floor(levelWidth / 2 / spacingL) + 1;
const c10 = Array.from({ length: 2 * kMax + 1 }, (_, i) => Math.round(xc + (i - kMax) * spacingL));
const left = c10[0];
const right = c10[c10.length - 1];
const n9 = Math.floor((left - COPING_END_GAP) / spacingS);
if (n9 < 0) {
throw new Error('RB-K01: C10 바깥 구간이 끝 여유보다 짧아 C9를 놓을 수 없습니다.');
}
const c9 = Array.from({ length: n9 }, (_, j) => Math.round(left - (n9 - j) * spacingS));
const c11 = Array.from({ length: n9 }, (_, j) => Math.round(right + (j + 1) * spacingS));
const endGap = Math.min(left - c9[0], coping - c11[c11.length - 1]);
return { c10, c9, c11, endGap: endGap };
}
/**
* Side horizontal bars (코핑철근.md §6): seven rows from the bottom at 250 mm.
* Rows below the sloped-bottom break (z_7,end) are C12, the rows at and above it are C13.
*/
export function sideRows(zBottom: number, zBreak: number, rows = 7): { c12: number[]; c13: number[] } {
const z = Array.from({ length: rows }, (_, i) => Math.round((zBottom + i * COPING_REBAR.spacingSide / 1000) * 1000) / 1000);
return { c12: z.filter((v) => v < zBreak - 1e-9), c13: z.filter((v) => v >= zBreak - 1e-9) };
}
/** C14 counts (코핑철근.md §8): 2 upper lines of 11 plus the lower rows 5 / 6 / 3 / 2 = 38. */
export const C14_COUNTS = { upperLines: 2, upperPerLine: 11, lower: [5, 6, 3, 2] as const };
export function c14Total(): number {
return C14_COUNTS.upperLines * C14_COUNTS.upperPerLine + C14_COUNTS.lower.reduce((a, b) => a + b, 0);
}
/** C15 (거꾸로 된 U, 가장 높은 계단) and C16 (L형, 2구간) counts (코핑철근.md §7). */
export const STEP_BAR_COUNTS = { C15: 11, C16: 22 } as const;