feat(rebar): 주철근 기본간격·끝단 여유를 입력과 연동, CP04 홀수 개수 경고
- widthLayout이 코핑 배근 입력(mainSpacing, mainEndGap)을 받는다. 결과에 spacing 필드 추가 - 3D 주철근 위치의 125 하드코딩 제거 (철근표와 3D가 같은 간격을 씀) - CP04: 주철근 개수 n+3이 홀수면 cycle-1·cycle-2 분할 불가 경고 (적용은 막지 않음) - P1 기본값(125 · 80)에서는 결과와 경고 없음 (테스트로 확인) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d2c5f90092
commit
1e6b8db7e9
4 files changed
+44
-12
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { DEFAULT_MATERIAL, fyOf, hookLength, Material, NOMINAL_DIAMETER, spliceLength } from './common';
|
||||
import { DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
|
||||
/**
|
||||
* C1–C8 상·하면 주철근 (plan C3 continued). Source: RAG/코핑철근.md §5, 2026-10-22 최종 정리.
|
||||
@@ -8,9 +8,6 @@ import { DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
export const MAIN = {
|
||||
/** 피복 (최외측 철근 중심까지). */
|
||||
cover: 100,
|
||||
/** 기본 간격 s_m and minimum end gap g_min. */
|
||||
spacing: 125,
|
||||
endGapMin: 80,
|
||||
/** 상면 단 가로 간격 = d (H29, mm). Fixed; the vertical step is the 상면 주철근 단 간격 input. */
|
||||
layHorizontal: NOMINAL_DIAMETER.H29,
|
||||
/** 90° 갈고리 l_h (mm, as in the document). */
|
||||
@@ -31,18 +28,24 @@ export interface WidthLayout {
|
||||
g: number;
|
||||
/** Bars in all: n + 3. */
|
||||
count: number;
|
||||
/** 기본간격 s_m (mm) used for this layout (the 주철근 기본간격 input). */
|
||||
spacing: number;
|
||||
/** Bars per cycle (alternating): 12 / 12 for 24. */
|
||||
cyclePerKind: number;
|
||||
/** Dimension string, e.g. "127 · 110.5 · 21@125 · 110.5 · 127". */
|
||||
text: string;
|
||||
}
|
||||
|
||||
/** 폭 방향 배치 (코핑철근.md §5.1). d_st = H25 stirrup, d_m = H29 main. */
|
||||
export function widthLayout(B: number, dSt = NOMINAL_DIAMETER.H25, dM = NOMINAL_DIAMETER.H29): WidthLayout {
|
||||
/**
|
||||
* 폭 방향 배치 (코핑철근.md §5.1). d_st = H25 stirrup, d_m = H29 main.
|
||||
* s_m (주철근 기본간격) and g_min (끝단 최소 여유) come from the 코핑 배근 input.
|
||||
*/
|
||||
export function widthLayout(B: number, s: Pick<CopingRebarSettings, 'mainSpacing' | 'mainEndGap'> = DEFAULT_COPING_REBAR, dSt = NOMINAL_DIAMETER.H25, dM = NOMINAL_DIAMETER.H29): WidthLayout {
|
||||
const yE = MAIN.cover + (dSt + dM) / 2;
|
||||
const S = B - 2 * yE;
|
||||
const n = Math.floor((S - 2 * MAIN.endGapMin) / MAIN.spacing);
|
||||
const g = (S - n * MAIN.spacing) / 2;
|
||||
const spacing = s.mainSpacing;
|
||||
const n = Math.floor((S - 2 * s.mainEndGap) / spacing);
|
||||
const g = (S - n * spacing) / 2;
|
||||
const count = n + 3;
|
||||
const r = (v: number) => Math.round(v * 10) / 10;
|
||||
return {
|
||||
@@ -51,8 +54,9 @@ export function widthLayout(B: number, dSt = NOMINAL_DIAMETER.H25, dM = NOMINAL_
|
||||
n,
|
||||
g: r(g),
|
||||
count,
|
||||
spacing,
|
||||
cyclePerKind: count / 2,
|
||||
text: `${r(yE)} · ${r(g)} · ${n}@${MAIN.spacing} · ${r(g)} · ${r(yE)}`,
|
||||
text: `${r(yE)} · ${r(g)} · ${n}@${spacing} · ${r(g)} · ${r(yE)}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -152,8 +152,12 @@ export function rebarSummary(
|
||||
rows.push({ member: 'bearing', name: 'S2', size: 'H19', count: blk.S2, length: barLength(1200, model.blockRebar), note: `블럭 배치 분리, 블럭당 8본 · 묻힘 ${range(emb2)} (블럭 상면 − 50)` });
|
||||
|
||||
// Coping (코핑철근.md §5–§8)
|
||||
const width = widthLayout(B);
|
||||
const width = widthLayout(B, model.copingRebar);
|
||||
const perRow = width.count / 2; // cycle split, 12 per row
|
||||
// CP04 (승인 2026-10-26): the cycle split needs an even count (n + 3), so n must be odd. Warning only; the input is kept.
|
||||
if (width.count % 2 !== 0) {
|
||||
warnings.push({ code: 'CP04', message: `주철근 개수 ${width.count}(n+3)은 홀수라 cycle-1·cycle-2를 나눌 수 없습니다 (기본간격 ${width.spacing}, 끝단 여유 ${model.copingRebar.mainEndGap}). 기본간격을 확인하세요.`, target: 'coping' });
|
||||
}
|
||||
// C1–C3 and C4–C6 are the same three top rows (row 1, 2, 3), one set per cycle.
|
||||
for (const [name, k] of [['C1', 1], ['C2', 2], ['C3', 3], ['C4', 1], ['C5', 2], ['C6', 3]] as const) {
|
||||
rows.push({ member: 'coping', name, size: 'H29', count: perRow, length: topBarLength(L, k), note: '상면, 이음 무시' });
|
||||
|
||||
Reference in new issue
Block a user