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:
ypshimandClaude Haiku 5.5 committed 2026-10-23 11:44:44 +09:00
1 parent 5b5db60657
commit 0a5edfb152
9 files changed
+169 -45

No files matched your search

+8 -6
View File
@@ -3,6 +3,7 @@ import type { PierModel } from '../core/geometry';
import { assemblyEndOffset, assemblyJs, b10Levels, b9Bars, FOOTING_DEFAULTS, gridPositions, grid, layers, legLength, legOffsets, sideDepth } from '../core/rebar/footing';
import { bottomPiece, MAIN, widthLayout } from '../core/rebar/coping-main';
import { C14_INSET, c14Bars, CAP, COPING_REBAR, SHEAR_LOOP_STEP, shearBars, shearBarsMulti, shearUHeight, copingSideBars, SIDE_HOOK_LEG, stairBars, undersideAt } from '../core/rebar/coping';
import { sideRowLevels } from '../core/coping-geom';
import { columnRebar, COLUMN_P1 } from '../core/rebar/column';
import { barsAcross, BLOCK_REBAR } from '../core/rebar/bearing-block';
import { blockFramePoint } from '../core/geometry';
@@ -150,8 +151,8 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
}
// Bottom bars C7 / C8 (코핑철근.md §5.2–5.3): they follow the sloped underside, 127 above it, with a vertical leg up
// at each end to the C1 level. Each bar is two pieces spliced at the column centre (overlap l_s). The slope runs x_L0 from each end (T형).
const xL0 = L / 2 - COPING_REBAR.levelWidth / 2000;
const under = (x: number) => undersideAt(L * 1000, x * 1000, m.endBottom, m.levelBottom);
const xL0 = L / 2 - m.copingGeom.levelWidth / 2000;
const under = (x: number) => undersideAt(L * 1000, x * 1000, m.endBottom, m.levelBottom, m.copingGeom.levelWidth);
const lap = bottomPiece(mCoping).ls / 2000;
xs.forEach((n, j) => {
const z = (x: number) => under(x) + 0.127;
@@ -169,7 +170,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
});
// Shear loops C9 / C10 / C11 and the gaps between columns: a closed U at each position.
const colS = m.columns.map((c) => c.s * 1000);
const sh = colS.length > 1 ? shearBarsMulti(L * 1000, colS) : { ...shearBars(L * 1000), between: [] as number[] };
const sh = colS.length > 1 ? shearBarsMulti(L * 1000, colS, m.copingGeom) : { ...shearBars(L * 1000, undefined, m.copingGeom), between: [] as number[] };
const loops: [string, number[]][] = [['C9', sh.c9], ['C10', sh.c10], ['C11', sh.c11], ['C9·C11 사이', sh.between]];
// Each position has three 폐합 (코핑철근.md §4.1): legs at y_i = c + i·s_leg (i = 0 … 5), 폐합 i = legs i and i + 3,
// 1740 wide. Each 폐합 is a 하부 U (base at the bottom, legs up to the top) and a 상부 삿갓 (top bar, legs down
@@ -181,7 +182,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
for (const [name, list] of loops) {
for (const x of list) {
const xm = mm(x);
const h = shearUHeight(x, L * 1000) / 1000;
const h = shearUHeight(x, L * 1000, m.copingGeom) / 1000;
const bot = top - h;
const capBot = top - (h - CAP.cover / 1000);
for (let i = 0; i < 3; i++) {
@@ -203,7 +204,8 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
// and two ㄷ bars: a body across the width at x_w, 25.4 above the row, with legs 1525 inward along the faces.
const sideFace = B / 2 - 0.127;
const dSide = NOMINAL_DIAMETER.H25;
const side = copingSideBars(L * 1000, 41.288, 42.538);
const levels = sideRowLevels(m.levelBottom);
const side = copingSideBars(L * 1000, levels.zBottom, levels.zBreak, m.copingGeom);
for (const [name, rows] of [['C12', side.c12], ['C13', side.c13]] as const) {
for (const r of rows) {
const xw = mm(r.xw);
@@ -223,7 +225,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
const c14Hook = mm(hookLength('main90', NOMINAL_DIAMETER.H19));
const c14Na = -B / 2 + mm(C14_INSET);
const c14Nb = B / 2 - mm(C14_INSET);
for (const b of c14Bars(L * 1000, topEl, [...side.c12, ...side.c13], (x) => undersideAt(L * 1000, x, m.endBottom, m.levelBottom))) {
for (const b of c14Bars(L * 1000, topEl, [...side.c12, ...side.c13], (x) => undersideAt(L * 1000, x, m.endBottom, m.levelBottom, m.copingGeom.levelWidth))) {
const xm = mm(b.x);
addBar('C14', 0, [xm, b.z, c14Na], [xm, b.z, c14Nb], NOMINAL_DIAMETER.H19, COLOR.coping);
// 연직 발 below the coping underside is left out (코핑철근.md §8).