From 4d5e3cc04e1266a84000bcc70abb1d28490b5dc4 Mon Sep 17 00:00:00 2001 From: ypshim Date: Fri, 23 Oct 2026 13:30:28 +0900 Subject: [PATCH] feat(rebar): P3 and P6 end at the coping middle level; e_top computed from it The coping middle level is (Level underside + step top)/2. P3's top and P6's upper limit are this level, and e_top is the step top minus it (P1: 1322, replacing the 1623 reverse-engineered value). On P1 P3 goes from 38 to 39 ties and P6 stays at 8 levels. With taper h2 = 3000 the middle level is 13275: P3 37 ties, P6 8 levels (32 bars), e_top 2072. Co-Authored-By: Claude Haiku 5.5 --- src/core/rebar/column.ts | 10 +++++++--- tests/column-model.test.ts | 11 +++++++++++ tests/rebar-column.test.ts | 8 ++++---- tests/rebar-summary.test.ts | 4 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/core/rebar/column.ts b/src/core/rebar/column.ts index b210319..07e597d 100644 --- a/src/core/rebar/column.ts +++ b/src/core/rebar/column.ts @@ -52,7 +52,9 @@ export function columnInputFor(model: PierModel, base: ColumnInput = COLUMN_P1): // P1 top = C3 − 100 (계산 2026-10-23), so e_P1 = step top − (C3 − 0.1) = 485 on P1. const c3 = model.copingRefTop - 0.127 - 2 * 0.0572; const eP1 = Math.round((seg.top - (c3 - 0.1)) * 1000); - return { ...base, Hc, hcop, eP1 }; + // e_top: the coping middle level (Level 하면 + 계단 상면)/2 is the top of P3 and P6 (승인 2026-10-23). + const eTop = Math.round((seg.top - (model.levelBottom + seg.top) / 2) * 1000); + return { ...base, Hc, hcop, eP1, eTop }; } export const COLUMN_P1: ColumnInput = { @@ -61,7 +63,8 @@ export const COLUMN_P1: ColumnInput = { hcop: 2644, c: 125, eP1: 485, - eTop: 1623, + // Coping middle level: (Level 하면 + 계단 상면)/2 on P1 = 42.233 → e_top 1322 (승인 2026-10-23, Q-C3 대체). + eTop: 1322, Hf: 2000, nDiv: 46, ctcCoupler: 3000, @@ -154,7 +157,8 @@ export function columnRebar(x: ColumnInput = COLUMN_P1, m: Material = DEFAULT_MA // P6 crossties (기둥철근.md §7): 4 bars per 단, from the first kept P4 const z4first = p4.length ? p4[0] : z5last; const p6Levels: number[] = []; - for (let z = z4first; z <= x.Hc; z += x.ctcP6) p6Levels.push(z); + // P6 runs up to the same top as P3, the coping middle level (승인 2026-10-23). + for (let z = z4first; z <= zTopT; z += x.ctcP6) p6Levels.push(z); const p6Straight = 2 * tieRadius; const p6Hook = hookLength('tie90', dH16); const p6Length = p6Straight + 2 * Math.round(p6Hook); // 135 mm per hook, as in the document diff --git a/tests/column-model.test.ts b/tests/column-model.test.ts index 38b0248..6746eac 100644 --- a/tests/column-model.test.ts +++ b/tests/column-model.test.ts @@ -24,4 +24,15 @@ describe('기둥 철근 높이는 모델에서 (Hc · h_cop, 승인 2026-10-23)' // The P1 top is anchored to the step top (and C3), so it does not move with h2. expect(col.zTop1).toBeCloseTo(14862, 0); }); + + it('P3 and P6 end at the coping middle level: P1 e_top 1322; taper 3000 gives e_top 2072, P3 37 ties, P6 32 bars', () => { + const p1 = columnInputFor(buildPier(loadP1())); + expect(p1.eTop).toBeCloseTo(1322, 0); + const high = columnInputFor(buildPier({ ...loadP1(), copingH2Mm: 3000 })); + expect(high.eTop).toBeCloseTo(2072, 0); + const col = columnRebar(high); + expect(col.zTopT).toBeCloseTo(13275, 0); + expect(col.p3Count).toBe(37); + expect(col.p6Count).toBe(32); + }); }); diff --git a/tests/rebar-column.test.ts b/tests/rebar-column.test.ts index 4b797d6..ae826eb 100644 --- a/tests/rebar-column.test.ts +++ b/tests/rebar-column.test.ts @@ -31,12 +31,12 @@ describe('기둥 철근 C4 (기둥철근.md, plan C4)', () => { expect(c.tieCircumference).toBeCloseTo(5657.7, 1); }); - it('P3: l_e = 2340, 38 ties from 2.340 at @300 (top 13.440)', () => { - expect(c.zTopT).toBe(13724); + it('P3: l_e = 2340, 39 ties from 2.340 at @300, top at the coping middle level 14.025 (승인 2026-10-23)', () => { + expect(c.zTopT).toBe(14025); expect(c.lE).toBe(2340); - expect(c.p3Count).toBe(38); + expect(c.p3Count).toBe(39); expect(c.p3[0]).toBe(2340); - expect(c.p3[c.p3.length - 1]).toBe(13440); + expect(c.p3[c.p3.length - 1]).toBe(13740); }); it('P5: 19 ties @120 from 2.220 down to 0.060', () => { diff --git a/tests/rebar-summary.test.ts b/tests/rebar-summary.test.ts index dce33b3..cc77061 100644 --- a/tests/rebar-summary.test.ts +++ b/tests/rebar-summary.test.ts @@ -24,12 +24,12 @@ describe('③ 철근표 요약 (P1)', () => { expect(count('C16')).toBe(22); }); - it('column: P1 230, P2 230, couplers 368, P3 38, P5 19, P4 8, P6 32', () => { + it('column: P1 230, P2 230, couplers 368, P3 39, P5 19, P4 8, P6 32', () => { expect(count('P1')).toBe(230); expect(count('P2')).toBe(230); expect(count('주철근 커플러')).toBe(368); expect(count('띠철근 커플러')).toBe(35); - expect(count('P3')).toBe(38); + expect(count('P3')).toBe(39); expect(count('P5')).toBe(19); expect(count('P4')).toBe(8); expect(count('P6')).toBe(32);