From 9b79083d5002215ada4c62704c9023919a832f56 Mon Sep 17 00:00:00 2001 From: ypshim Date: Mon, 26 Oct 2026 12:25:15 +0900 Subject: [PATCH] =?UTF-8?q?fix(bearing):=20C4=C2=B7C5=20are=20the=20?= =?UTF-8?q?=EA=B5=90=EC=B6=95=20distances=20from=20the=20bearing=20to=20th?= =?UTF-8?q?e=20block=20edges=20(=EC=8A=B9=EC=9D=B8=202026-10-26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bearingEdgeDistances now reads the block geometry: 분리 1200 blocks are centred on the bearing (600 / 600); 일체 uses the pair's 2500 block (outer margins 601, within the 5 mm tolerance of 600). - The plan labels C4 and C5 from these values; the coping-edge definition is removed. Co-Authored-By: Claude Haiku 5.5 --- src/core/bearing-layout.ts | 28 +++++++++++++++++----------- src/view/bearing-plan-svg.ts | 4 +--- tests/bearing-layout.test.ts | 20 ++++++++++++++------ tests/bearing-plan-svg.test.ts | 6 +++--- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/core/bearing-layout.ts b/src/core/bearing-layout.ts index 799555e..2b8092a 100644 --- a/src/core/bearing-layout.ts +++ b/src/core/bearing-layout.ts @@ -2,7 +2,7 @@ import type { BlockModel, PierModel } from './geometry'; /** * 받침 배치 규칙 (승인 2026-10-26). - * - C4·C5: 코핑 가장자리(교각축 직각, 폭 B의 두 가장자리)와 받침 중심 사이 거리. 모델값을 쓰고 도면값과 비교한다. + * - C4·C5: 교축 방향, 받침 중심과 받침블럭 연단 사이 거리 (승인 2026-10-26). 블록 형상에서 계산하고 도면값과 비교한다. * - 일체: 같은 순서끼리 (전열 1 · 후열 1, 전열 2 · 후열 2 …, 각 열의 번호 순) 두 받침의 편심거리가 100 mm를 넘으면 분리를 우선한다. * (P1 은 전열 1–5, 후열 6–10 으로 번호가 매겨져 있어서 번호 자체가 아니라 열 안의 순서로 짝짓는다.) * 편심거리 = 두 받침 중심의 교각축 방향 차이 |s(전열) − s(후열)|. @@ -12,9 +12,9 @@ export const PAIR_ECCENTRICITY_LIMIT_MM = 100; export interface EdgeDistance { no: number; row: BlockModel['row']; - /** 교각축 직각 방향: 코핑 한쪽 가장자리(n = −B/2)에서 받침 중심까지 (mm) = C4. */ + /** 교축 방향: 받침 중심에서 블록의 낮은 쪽(−n) 연단까지 (mm) = C4. */ leftMm: number; - /** 받침 중심에서 코핑 다른 가장자리(n = +B/2)까지 (mm) = C5. */ + /** 교축 방향: 받침 중심에서 블록의 높은 쪽(+n) 연단까지 (mm) = C5. */ rightMm: number; } @@ -27,15 +27,21 @@ export interface PairEccentricity { allowed: boolean; } -/** C4·C5 from the model: distances from the two coping edges (±B/2, across the coping width) to each bearing centre (mm). */ +/** + * C4·C5 from the block geometry: distances along the 교축 from each bearing centre to the block edges (mm). + * 분리: the 1200 block is centred on its bearing, so both are 600. 일체: the pair's 2500 block, so the outer + * margins are 600 (C1) and the inner ones run to the other bearing. + */ export function bearingEdgeDistances(m: PierModel): EdgeDistance[] { - const half = m.copingB / 2; - return m.blocks.map((b) => ({ - no: b.no, - row: b.row, - leftMm: (b.n + half) * 1000, - rightMm: (half - b.n) * 1000, - })); + const HALF_SEPARATE = 0.6; // 1200 / 2, m + 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 }; + }); } /** diff --git a/src/view/bearing-plan-svg.ts b/src/view/bearing-plan-svg.ts index 2a3e912..e1c467a 100644 --- a/src/view/bearing-plan-svg.ts +++ b/src/view/bearing-plan-svg.ts @@ -57,14 +57,12 @@ export function bearingPlanSvg(m: PierModel, pairIndex: number, overlay?: Bearin parts.push(`${b.no}`); } - // Dimensions: C2 between the bearing centres, C4 and C5 from the coping edges (교각축 직각), C1 to the block edges. + // Dimensions: C2 between the bearing centres, C4 and C5 from the bearing to the block edges (교축). const dist = bearingEdgeDistances(m); const d = (no: number) => dist.find((x) => x.no === no)!; - const half = m.copingB / 2; 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(`코핑 폭 B ${Math.round(m.copingB * 1000)}`); return `${parts.join('')}`; } diff --git a/tests/bearing-layout.test.ts b/tests/bearing-layout.test.ts index aa64a13..74d1ac7 100644 --- a/tests/bearing-layout.test.ts +++ b/tests/bearing-layout.test.ts @@ -5,6 +5,8 @@ import { validatePier } from '../src/core/validate'; import type { Issue } from '../src/core/types'; import { loadP1 } from './helpers'; +const integrated = buildPier({ ...loadP1(), bearingLayout: '일체' }); + const model = buildPier(loadP1()); function block(no: number, row: '전열' | '후열', s: number): BlockModel { @@ -12,14 +14,20 @@ function block(no: number, row: '전열' | '후열', s: number): BlockModel { } describe('받침 배치 규칙 (승인 2026-10-26)', () => { - it('C4 and C5 from the model: distances from the two coping edges across the width (교각축 직각), P1 front 852 / 2248', () => { + it('C4 and C5 from the block edges along the 교축: 분리 blocks are centred, so both are 600', () => { const d = bearingEdgeDistances(model); expect(d).toHaveLength(10); - const first = d.find((x) => x.no === 1 && x.row === '전열')!; - expect(first.leftMm).toBeCloseTo(852, 0); - expect(first.rightMm).toBeCloseTo(2248, 0); - // the two edges are one coping width (3100) apart - for (const x of d) expect(x.leftMm + x.rightMm).toBeCloseTo(3100, 6); + for (const x of d) { + expect(x.leftMm).toBeCloseTo(600, 0); + expect(x.rightMm).toBeCloseTo(600, 0); + } + }); + + it('일체: the outer margins stay 600 (C4 of the front bearing, C5 of the back bearing)', () => { + const d = bearingEdgeDistances(integrated); + // 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); }); it('the front and back bearings of one number are about 85 mm apart on P1, so 일체 is allowed', () => { diff --git a/tests/bearing-plan-svg.test.ts b/tests/bearing-plan-svg.test.ts index 70e0925..90d4527 100644 --- a/tests/bearing-plan-svg.test.ts +++ b/tests/bearing-plan-svg.test.ts @@ -7,10 +7,10 @@ const separate = buildPier(loadP1()); const integrated = buildPier({ ...loadP1(), bearingLayout: '일체' }); describe('교량받침 상세 평면 (승인 2026-10-26)', () => { - it('shows C4 and C5 across the coping width (P1 front 852 / 2248)', () => { + it('shows C4 and C5 from the bearing to the block edges along the 교축 (600 each)', () => { const svg = bearingPlanSvg(separate, 0); - expect(svg).toContain('C4 852'); - expect(svg).toContain('C5 950'); + expect(svg).toContain('C4 600'); + expect(svg).toContain('C5 600'); }); it('분리 draws two 1200 outlines; 일체 draws one 2500 outline (block outline only)', () => {