diff --git a/src/core/bearing-layout.ts b/src/core/bearing-layout.ts index 2b8092a..4b0d94a 100644 --- a/src/core/bearing-layout.ts +++ b/src/core/bearing-layout.ts @@ -12,10 +12,10 @@ export const PAIR_ECCENTRICITY_LIMIT_MM = 100; export interface EdgeDistance { no: number; row: BlockModel['row']; - /** 교축 방향: 받침 중심에서 블록의 낮은 쪽(−n) 연단까지 (mm) = C4. */ - leftMm: number; - /** 교축 방향: 받침 중심에서 블록의 높은 쪽(+n) 연단까지 (mm) = C5. */ - rightMm: number; + /** 교축 방향: 받침 중심에서 블록의 낮은 쪽(−n) 연단까지 (mm) = C4. null = 쌍 안쪽 (C4·C5 아님). */ + leftMm: number | null; + /** 교축 방향: 받침 중심에서 블록의 높은 쪽(+n) 연단까지 (mm) = C5. null = 쌍 안쪽 (C4·C5 아님). */ + rightMm: number | null; } export interface PairEccentricity { @@ -37,10 +37,18 @@ export function bearingEdgeDistances(m: PierModel): EdgeDistance[] { const HALF_INTEGRATED = 1.25; // 2500 / 2, m return m.blocks.map((b) => { const host = m.integratedBlocks.find((x) => (b.row === '전열' ? x.frontNo : x.backNo) === b.no); - const half = host ? HALF_INTEGRATED : HALF_SEPARATE; - const low = host ? host.n - half : b.n - half; - const high = host ? host.n + half : b.n + half; - return { no: b.no, row: b.row, leftMm: (b.n - low) * 1000, rightMm: (high - b.n) * 1000 }; + if (!host) { + return { no: b.no, row: b.row, leftMm: (HALF_SEPARATE) * 1000, rightMm: HALF_SEPARATE * 1000 }; + } + // 일체: only the outer edges are C4 (front, low side) and C5 (back, high side); the inner side faces the other bearing. + const low = host.n - HALF_INTEGRATED; + const high = host.n + HALF_INTEGRATED; + return { + no: b.no, + row: b.row, + leftMm: b.row === '전열' ? (b.n - low) * 1000 : null, + rightMm: b.row === '후열' ? (high - b.n) * 1000 : null, + }; }); } diff --git a/src/main.ts b/src/main.ts index 912c424..62e2d53 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1576,13 +1576,14 @@ function renderBearingLayout(wrap: HTMLDivElement, pier: Pier): void { const table = el('table', undefined, 'grid-table rebar-table'); const head = el('thead'); const hr = el('tr'); - for (const h of ['받침', '열', 'C4 (코핑 시작 ↔ 받침, mm)', 'C5 (받침 ↔ 코핑 끝, mm)']) hr.appendChild(el('th', h)); + for (const h of ['받침', '열', 'C4 (교축 · 받침 ↔ 블록 바깥 연단, mm)', 'C5 (교축 · 받침 ↔ 블록 바깥 연단, mm)']) hr.appendChild(el('th', h)); head.appendChild(hr); table.appendChild(head); const body = el('tbody'); for (const e of edges) { const tr = el('tr'); - for (const v of [String(e.no), e.row, e.leftMm.toFixed(0), e.rightMm.toFixed(0)]) tr.appendChild(el('td', v)); + const fmt = (v: number | null) => (v === null ? '—' : v.toFixed(0)); + for (const v of [String(e.no), e.row, fmt(e.leftMm), fmt(e.rightMm)]) tr.appendChild(el('td', v)); body.appendChild(tr); } table.appendChild(body); diff --git a/src/view/bearing-plan-svg.ts b/src/view/bearing-plan-svg.ts index e1c467a..49ffe93 100644 --- a/src/view/bearing-plan-svg.ts +++ b/src/view/bearing-plan-svg.ts @@ -61,8 +61,8 @@ export function bearingPlanSvg(m: PierModel, pairIndex: number, overlay?: Bearin const dist = bearingEdgeDistances(m); const d = (no: number) => dist.find((x) => x.no === no)!; parts.push(`C2 ${Math.round(Math.abs(k.n - f.n) * 1000)}`); - parts.push(`C4 ${Math.round(d(f.no).leftMm)}`); - parts.push(`C5 ${Math.round(d(k.no).rightMm)}`); + parts.push(`C4 ${Math.round(d(f.no).leftMm ?? 0)}`); + parts.push(`C5 ${Math.round(d(k.no).rightMm ?? 0)}`); return `${parts.join('')}`; } diff --git a/tests/bearing-layout.test.ts b/tests/bearing-layout.test.ts index 74d1ac7..e2c3b6f 100644 --- a/tests/bearing-layout.test.ts +++ b/tests/bearing-layout.test.ts @@ -28,6 +28,9 @@ describe('받침 배치 규칙 (승인 2026-10-26)', () => { // The 2500 block is centred on the pair midpoint, so the outer margins are 601 (within the 5 mm drawing tolerance of 600). expect(d.find((x) => x.no === 1 && x.row === '전열')!.leftMm).toBeCloseTo(600, -1); expect(d.find((x) => x.no === 6 && x.row === '후열')!.rightMm).toBeCloseTo(600, -1); + // the inner sides face the other bearing of the pair: no C4 or C5 there + expect(d.find((x) => x.no === 1 && x.row === '전열')!.rightMm).toBeNull(); + expect(d.find((x) => x.no === 6 && x.row === '후열')!.leftMm).toBeNull(); }); it('the front and back bearings of one number are about 85 mm apart on P1, so 일체 is allowed', () => {