diff --git a/src/view/block-rebar-plan-svg.ts b/src/view/block-rebar-plan-svg.ts index 3ca2102..32b971f 100644 --- a/src/view/block-rebar-plan-svg.ts +++ b/src/view/block-rebar-plan-svg.ts @@ -24,7 +24,7 @@ export function blockRebarPlanSvg(m: PierModel, pairIndex = 0): string { const parts: string[] = []; // One block: a = along the 교각축 (s), c = along the 교축 (n), both in metres from the block centre, turned by the row skew. - const drawBlock = (cs: number, cn: number, skew: number, wA: number, wC: number) => { + const drawBlock = (cs: number, cn: number, skew: number, wA: number, wC: number, side: 1 | -1) => { const P = (a: number, c: number): [number, number] => { const [sv, nv] = blockFramePoint({ s: cs, n: cn, rowSkewDeg: skew }, a, c); return [X(nv), Y(sv)]; @@ -62,7 +62,9 @@ export function blockRebarPlanSvg(m: PierModel, pairIndex = 0): string { const a1d = barsAcross(wA * 1000, s.spacingS1, s); const [bx, by] = P(wA / 2 + 0.22, 0); parts.push(`${layout(a2d.count, a2d.spacing, a2d.firstEnd)}`); - const [rx, ry] = P(0, wC / 2 + 0.22); + // The S1 layout goes on the outer side of the block (the front block on the left, the back block on the right), + // so it never falls into the gap between the two blocks. + const [rx, ry] = P(0, side * (wC / 2 + 0.22)); // The S1 layout runs along the 교각축 (vertical in the plan), so its text is turned to read along that dimension line. parts.push(`${layout(a1d.count, a1d.spacing, a1d.firstEnd)}`); const [wx, wy] = P(-wA / 2 - 0.2, 0); @@ -71,14 +73,15 @@ export function blockRebarPlanSvg(m: PierModel, pairIndex = 0): string { }; if (ib) { - const P = drawBlock(ib.s, ib.n, ib.rowSkewDeg, INTEGRATED_BLOCK.depth / 1000, INTEGRATED_BLOCK.length / 1000); + const P = drawBlock(ib.s, ib.n, ib.rowSkewDeg, INTEGRATED_BLOCK.depth / 1000, INTEGRATED_BLOCK.length / 1000, 1); // Row numbers: S2 and S1 once each, at the first bar's end. const [sx, sy] = P(-0.6 + 0.1, -1.25 + 0.1); parts.push(`S2`); parts.push(`S1`); parts.push(`${INTEGRATED_BLOCK.length}`); } else { - for (const b of [f, k]) drawBlock(b.s, b.n, b.rowSkewDeg, 1.2, 1.2); + drawBlock(f.s, f.n, f.rowSkewDeg, 1.2, 1.2, -1); + drawBlock(k.s, k.n, k.rowSkewDeg, 1.2, 1.2, 1); const [sx, sy] = [X(f.n) - 500, Y(f.s) - 500]; parts.push(`S2`); parts.push(`S1`); diff --git a/tests/block-rebar-plan-svg.test.ts b/tests/block-rebar-plan-svg.test.ts index 256ec1e..b9967ca 100644 --- a/tests/block-rebar-plan-svg.test.ts +++ b/tests/block-rebar-plan-svg.test.ts @@ -40,3 +40,10 @@ describe('받침블럭 배근 평면 치수 (승인 2026-10-26)', () => { expect(svg).toContain('@125=2250'); }); }); + +describe('받침블럭 배근 평면 · S1 치수 위치 (승인 2026-10-26)', () => { + it('each S1 layout is written once, on the outer side of its block (front left, back right)', () => { + const svg = blockRebarPlanSvg(buildPier(loadP1()), 0); + expect(svg.split('7@125=875').length - 1).toBe(4); // S2 and S1 for each of the two blocks + }); +});