feat(rebar): P1 top = C3 − 100 with e_P1 computed; coupler rule keeps 2.5 m below the P1 top

e_P1 is no longer an input: P1 top = C3 (lowest coping top − 127 − 2·57.2 = 43.170) − 100 = 43.070, so e_P1 = step top −
43.070 = 485 mm. The P1 top moves from 15147 to 14862 mm; the top piece shortens by 285 mm. Couplers are placed at k·3000
with at least 2500 mm below the P1 top (a value to confirm). On P1 the coupler count stays at four (3, 6, 9, 12 m). P2 and
the tie top do not change.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-23 13:19:09 +09:00
1 parent f37a0bf9ce
commit f989315e02
3 files changed
+19 -10

No files matched your search

+12 -3
View File
@@ -27,6 +27,8 @@ export interface ColumnInput {
ctcCoupler: number;
/** P2 커플러를 P1보다 올리는 높이. */
dzCp2: number;
/** 커플러는 P1 위 끝에서 이 거리(mm) 이상 아래에만 둔다 (커플러 여유, 가정 2500). */
couplerTopMargin?: number;
ctcP3: number;
ctcP5: number;
ctcP4: number;
@@ -46,7 +48,11 @@ export function columnInputFor(model: PierModel, base: ColumnInput = COLUMN_P1):
const seg = model.segments.find((g) => col.s >= g.s0 - 1e-9 && col.s <= g.s1 + 1e-9) ?? model.segments[0];
const Hc = Math.round((model.levelBottom - model.footings[0].top) * 1000 * 10) / 10;
const hcop = Math.round((seg.top - model.levelBottom) * 1000 * 10) / 10;
return { ...base, Hc, hcop };
// C3 (상면 3단) = the lowest coping top −127 (C1 cover) −2·57.2 (layer spacing 상면 주철근 단 간격); P1: 43.170.
// 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 };
}
export const COLUMN_P1: ColumnInput = {
@@ -54,7 +60,7 @@ export const COLUMN_P1: ColumnInput = {
Hc: 12703,
hcop: 2644,
c: 125,
eP1: 200,
eP1: 485,
eTop: 1623,
Hf: 2000,
nDiv: 46,
@@ -113,7 +119,10 @@ export function columnRebar(x: ColumnInput = COLUMN_P1, m: Material = DEFAULT_MA
const zTop2 = x.Hc + lD2;
// Bottom of P1 and P2: 확대기초 하면 2단 (B7) 위 + (d_B7 + d_P1)/2 (기둥철근.md §3.2, the same for both).
const zBot = -x.Hf + layers(x.Hf).B7 + (NOMINAL_DIAMETER.S19 + dS32) / 2;
const couplerLevels = Array.from({ length: Math.max(0, Math.floor(zTop1 / x.ctcCoupler) - 1) }, (_, i) => (i + 1) * x.ctcCoupler);
// Couplers at k·ctc from the footing, kept at least the margin below the P1 top (커플러 여유).
const couplerMargin = x.couplerTopMargin ?? 2500;
const couplerCount = Math.max(0, Math.floor((zTop1 - couplerMargin) / x.ctcCoupler));
const couplerLevels = Array.from({ length: couplerCount }, (_, i) => (i + 1) * x.ctcCoupler);
// Pieces of each main bar between its couplers (기둥철근.md §3.2): the bottom piece carries the 90° hook (16.5·d = 525).
const p1Hook = Math.round(hookLength('main90', dS32));
const p1Points = [zBot, ...couplerLevels, zTop1];
+3 -3
View File
@@ -10,7 +10,7 @@ describe('기둥 철근 높이는 모델에서 (Hc · h_cop, 승인 2026-10-23)'
expect(input.hcop).toBeCloseTo(2644, 0);
const col = columnRebar(input);
expect(col.zTop2).toBeCloseTo(14539, 0);
expect(col.zTop1).toBeCloseTo(15147, 0);
expect(col.zTop1).toBeCloseTo(14862, 0);
});
it('taper h2 = 3000: Level underside 39.411, Hc 11203, P2 top 13039 (= Level underside + l_d)', () => {
@@ -21,7 +21,7 @@ describe('기둥 철근 높이는 모델에서 (Hc · h_cop, 승인 2026-10-23)'
expect(input.hcop).toBeCloseTo(4144, 0);
const col = columnRebar(input);
expect(col.zTop2).toBeCloseTo(13039, 0);
// The P1 top is anchored to the step top, so it does not move with h2.
expect(col.zTop1).toBeCloseTo(15147, 0);
// The P1 top is anchored to the step top (and C3), so it does not move with h2.
expect(col.zTop1).toBeCloseTo(14862, 0);
});
});
+4 -4
View File
@@ -10,8 +10,8 @@ describe('기둥 철근 C4 (기둥철근.md, plan C4)', () => {
expect(c.angleStepDeg).toBeCloseTo(360 / 46, 9);
});
it('heights: P1 top 15147, P2 top ≈ 14539 (l_d of S32 at fck 27, 1836.9 ≈ the document 1836)', () => {
expect(c.zTop1).toBe(15147);
it('heights: P1 top 14862 (= C3 43.170 − 0.1, e_P1 485), P2 top ≈ 14539 (l_d of S32 at fck 27, 1836.9 ≈ the document 1836)', () => {
expect(c.zTop1).toBe(14862);
expect(Math.abs(c.zTop2 - 14539)).toBeLessThan(1);
});
@@ -86,10 +86,10 @@ describe('RB-C07 P4 삭제 규칙 (기둥철근.md §6.2)', () => {
});
describe('기둥철근 P1·P2 마디와 바닥 (기둥철근.md §3.2)', () => {
it('bottom at −1697.5 (−H_f + z_B7 + (d_B7 + d_P1)/2), P1 pieces 4697.5 + 525 / 3000 ×3 / 3147', () => {
it('bottom at −1697.5 (−H_f + z_B7 + (d_B7 + d_P1)/2), P1 pieces 4697.5 + 525 / 3000 ×3 / 2862', () => {
expect(c.zBot).toBeCloseTo(-1697.55, 1);
expect(c.p1Hook).toBe(525);
expect(c.p1Pieces.map((v) => Math.round(v))).toEqual([5223, 3000, 3000, 3000, 3147]);
expect(c.p1Pieces.map((v) => Math.round(v))).toEqual([5223, 3000, 3000, 3000, 2862]);
});
it('P2 pieces 4847.5 / 3000 ×3 / 2389', () => {