feat(rebar): 계단부 C15·C16을 모델의 실제 계단으로 만든다 (T형·다주형 공통)
T형은 P1 문서의 고정 위치(2.196~12.000 m)·높이·11개를 써서 코핑 길이가 다르면 철근이 코핑 밖으로 나갔고, 다주형은 높은 계단 전체에 C15 하나만 두었다. 공통 규칙 (step-bars.ts): - 열마다(전·후열 단차가 있으면 각 쪽) 최저 상면 + h_16(100) 이상 구간이 계단, 경계는 mm 반올림 - 이웃보다 모두 높은 구간 C15(⊓), 나머지 계단 C16(L형, 낮은 쪽 다리, 높은 쪽으로 l_d 연장) - 폭 방향: T형은 주철근 내부 격자 하나 건너, 다주형은 상면 주철근 하나 건너 - 양쪽이 높은 계단은 RB-S01 알림, RB-M04 폐지. 꺾임은 편 좌표의 한 개(꺾은 철근) P1 문서값(C15 11 × 3852, C16 22 × 4070/4069, 137.5 · 10@250)을 그대로 재현한다. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9f336e2be4
commit
7340f8c1a1
8 files changed
+263
-105
No files matched your search
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
import type { PierModel } from '../geometry';
|
||||
import { DEFAULT_MATERIAL, developmentLength, fyOf, hookLength, type Material, NOMINAL_DIAMETER, spliceLength } from './common';
|
||||
import { stepBars } from './step-bars';
|
||||
|
||||
export type CopingPoint = [number, number, number];
|
||||
export interface CopingBar { name: string; size: string; diameterMm: number; pts: CopingPoint[]; length: number }
|
||||
@@ -48,7 +49,7 @@ export const MULTI_REBAR = {
|
||||
standardMm: 8000,
|
||||
/** C14: vertical pitch, pitch along the axis, stagger between rows. */
|
||||
c14Vertical: 0.6, c14Along: 1.2, c14Stagger: 0.6,
|
||||
/** h_16: a step at least this much above the end top gets C15 (m). */
|
||||
/** h_16: a step at least this much above the row's lowest top gets C15 / C16 (m, step-bars.ts). */
|
||||
stepMin: 0.1,
|
||||
} as const;
|
||||
|
||||
@@ -283,18 +284,12 @@ export function multicolCopingInfo(model: PierModel, material: Material = DEFAUL
|
||||
}
|
||||
});
|
||||
|
||||
// --- C15 계단부 (§8): 끝단보다 h_16 이상 높은 계단 전체에 ⊓ 하나 ------------------------------------------
|
||||
const front = model.segments;
|
||||
const endTop = Math.min(front[0].top, front.at(-1)!.top);
|
||||
const high = front.filter(g => g.top - endTop >= MULTI_REBAR.stepMin - 1e-9);
|
||||
if (high.length) {
|
||||
const from = high[0].s0 + c, to = high.at(-1)!.s1 - c;
|
||||
const z15 = Math.min(...high.map(g => g.top)) - c;
|
||||
const ld = developmentLength(d('H19'), fy('H19'), material.fck) / 1000;
|
||||
top.filter((_, i) => i % 2 === 0).forEach(y => add('C15', 'H19', [[from, z15 - ld, y], [from, z15, y], [to, z15, y], [to, z15 - ld, y]]));
|
||||
const above = Math.max(...front.map(g => g.top)) - (z15 + c);
|
||||
if (above > MULTI_REBAR.stepMin + 1e-9) warnings.push({ code: 'RB-M04', message: `가장 높은 계단 상면이 C15보다 ${Math.round(above * 1000)} mm 높습니다 (h_16 ${MULTI_REBAR.stepMin * 1000} 초과). C16 병행은 미정 (Q-M7).` });
|
||||
}
|
||||
// --- C15 · C16 계단부: T형과 같은 규칙 (결정 2026-11-10, step-bars.ts) ---------------------------------------
|
||||
// 가장 높은 계단마다 ⊓ (C15), 그 밖의 계단(최저 상면 + h_16 이상)마다 L형 (C16). 폭 방향은 상면 주철근 하나 건너.
|
||||
const stairs = stepBars(model, { cover: c * 1000, ld: Math.round(developmentLength(d('H19'), fy('H19'), material.fck)), d: d('H19'),
|
||||
stepMin: MULTI_REBAR.stepMin * 1000, across: top.filter((_, i) => i % 2 === 0) });
|
||||
for (const b of stairs.bars) add(b.name, 'H19', b.pts.map(([x, z]): CopingPoint => [x / 1000, z, b.n]));
|
||||
for (const message of stairs.warnings) warnings.push({ code: 'RB-S01', message });
|
||||
|
||||
// RB-M03: 상면 1단 외 철근이 12 m를 넘으면 이음 미정 (Q-M12).
|
||||
const long = [...new Set(bars.filter(x => !['C1', 'C4'].includes(x.name) && x.length > 12000).map(x => x.name))];
|
||||
|
||||
Reference in new issue
Block a user