feat(rebar,view): coping end height h1, taper h2 and Level width as inputs on ② (1단계)
The three values are inputs on the coping card, with the P1 values (1000 · 1500 · 2100) when absent, and they are tracked like the other shape inputs. The geometry and the coping rebar read them from one CopingGeom: the U heights follow the closed form (h1 − 2c) + h2·min(x_s, x_L0)/x_L0, which reproduces the P1 values. The side rows are assumed to keep their position relative to the Level underside (명세 확인 필요). P1 results are unchanged; the full suite passes. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5b5db60657
commit
0a5edfb152
9 files changed
+169
-45
No files matched your search
@@ -2,6 +2,7 @@ import type { PierModel } from '../geometry';
|
||||
import { barLength, bearingBlockRebar, totals } from './bearing-block';
|
||||
import { bottomPiece, topBarLength, widthLayout } from './coping-main';
|
||||
import { shearBars, shearBarsMulti, copingSideBars, SIDE_HOOK_LEG, c14Bars, c14Length, stairBars, stepDevLength, undersideAt, shearULength, capLength, PIECES_PER_POSITION } from './coping';
|
||||
import { sideRowLevels } from '../coping-geom';
|
||||
import { columnRebar, COLUMN_P1 } from './column';
|
||||
import { bottomBars, crossBars, sideBars, assemblyBars, shearB9 } from './footing';
|
||||
import { DEFAULT_MATERIAL, FckByMember, fyOf, isAssumedMaterial, Material, materialFor, splitPieces } from './common';
|
||||
@@ -162,21 +163,22 @@ export function rebarSummary(
|
||||
rows.push({ member: 'coping', name: 'C8', size: 'H29', count: perRow, length: bottom.piece, note: '하면, 2조각 겹침이음' });
|
||||
const colS = model.columns.map((c) => c.s * 1000);
|
||||
const nCol = Math.max(1, colS.length);
|
||||
const shear = nCol > 1 ? shearBarsMulti(L, colS) : { ...shearBars(L), between: [] as number[] };
|
||||
const geom = model.copingGeom;
|
||||
const shear = nCol > 1 ? shearBarsMulti(L, colS, geom) : { ...shearBars(L, undefined, geom), between: [] as number[] };
|
||||
const uRange = (xs: number[]) => {
|
||||
const u = xs.map((x) => Math.round(shearULength(x, L)));
|
||||
const u = xs.map((x) => Math.round(shearULength(x, L, geom)));
|
||||
return `${Math.min(...u)}–${Math.max(...u)}`;
|
||||
};
|
||||
const capRange = (xs: number[]) => {
|
||||
const c = xs.map((x) => Math.round(capLength(x, L)));
|
||||
const c = xs.map((x) => Math.round(capLength(x, L, geom)));
|
||||
return `${Math.min(...c)}–${Math.max(...c)}`;
|
||||
};
|
||||
const shearNote = (label: string, xs: number[]) =>
|
||||
`${label}, 하부 U ${uRange(xs)}, 삿갓 ${capRange(xs)} (l_cap 추천안, Q-K5), 조각 ${xs.length * PIECES_PER_POSITION}`;
|
||||
// Each position has three 폐합, each with one 하부 U and one 삿갓 (6 pieces). Pieces: U and 삿갓 lengths at each position.
|
||||
const loopPieces = (xs: number[]) => xs.flatMap((x) => [
|
||||
{ length: shearULength(x, L), count: 3 },
|
||||
{ length: capLength(x, L), count: 3 },
|
||||
{ length: shearULength(x, L, model.copingGeom), count: 3 },
|
||||
{ length: capLength(x, L, model.copingGeom), count: 3 },
|
||||
]);
|
||||
rows.push({ member: 'coping', name: 'C9', size: 'H25', count: shear.c9.length, length: null, pieces: loopPieces(shear.c9), note: shearNote('전단 좌 @250', shear.c9) });
|
||||
rows.push({ member: 'coping', name: 'C10', size: 'H25', count: shear.c10.length, length: null, pieces: loopPieces(shear.c10), note: shearNote('전단 Level @300', shear.c10) });
|
||||
@@ -188,7 +190,8 @@ export function rebarSummary(
|
||||
warnings.push({ code: 'RB-M01', message: `다주형 ${nCol}기둥: C14는 T형 기준으로 두었습니다 (기둥마다 반복 규칙 미정, Q-K11).`, target: 'coping' });
|
||||
}
|
||||
// Per row: two 일자 (side faces) and two ㄷ (one at each end), so 4 bars per row (코핑철근.md §6.2).
|
||||
const side = copingSideBars(model.copingL * 1000, 41.288, 42.538);
|
||||
const levels = sideRowLevels(model.levelBottom);
|
||||
const side = copingSideBars(model.copingL * 1000, levels.zBottom, levels.zBreak, model.copingGeom);
|
||||
const hook = model.copingB * 1000 - 2 * 127 + 2 * SIDE_HOOK_LEG; // ㄷ body across the width + two legs
|
||||
const c12Range = side.c12.length ? `${Math.round(side.c12[0].straight)}–${Math.round(side.c12[side.c12.length - 1].straight)}` : '—';
|
||||
// Per bar: 2 일자 (straight) and 2 ㄷ (hook body + legs), so 4 bars per row position.
|
||||
@@ -197,7 +200,7 @@ export function rebarSummary(
|
||||
rows.push({ member: 'coping', name: 'C13', size: 'H25', count: 4 * side.c13.length, length: null, pieces: sidePieces(side.c13), note: `측면, 끝면까지, 일자 (${2 * side.c13.length}) · ㄷ ${Math.round(hook)} (${2 * side.c13.length})` });
|
||||
// C14 / C15 / C16 are derived from the model (코핑철근.md §7–8); the document's 38 / 11 / 22 and 3852 / 4070 / 4069 are checked in the tests.
|
||||
const L14 = model.copingL * 1000;
|
||||
const c14 = c14Bars(L14, model.copingRefTop, [...side.c12, ...side.c13], (x) => undersideAt(L14, x, model.endBottom, model.levelBottom));
|
||||
const c14 = c14Bars(L14, model.copingRefTop, [...side.c12, ...side.c13], (x) => undersideAt(L14, x, model.endBottom, model.levelBottom, model.copingGeom.levelWidth));
|
||||
const lineCount = (line: number) => c14.filter((b) => b.line === line).length;
|
||||
const omitted = c14.filter((b) => !b.legs).length;
|
||||
rows.push({ member: 'coping', name: 'C14', size: 'H19', count: c14.length, length: c14Length(model.copingB * 1000), note: `위 2 줄 ${lineCount(1)} · ${lineCount(2)}본씩, 아래 ${[3, 4, 5, 6].map(lineCount).join(' · ')} (합 ${c14.length}) · 연직 발 생략 ${omitted}개 (하면 밖)` });
|
||||
|
||||
Reference in new issue
Block a user