fix(rebar): S1 layout dimensions on the outer side of each block in the plan

- The front block's S1 layout goes on the left and the back block's on the right,
  so the text no longer falls into the gap between the two blocks.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-26 14:22:00 +09:00
1 parent f1b2a0241d
commit 32e8dad7dc
2 files changed
+14 -4

No files matched your search

+7 -4
View File
@@ -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(`<text x="${bx}" y="${by}" text-anchor="middle" font-size="80" fill="#0F5C66">${layout(a2d.count, a2d.spacing, a2d.firstEnd)}</text>`);
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(`<text x="${rx}" y="${ry}" transform="rotate(-90 ${rx} ${ry})" text-anchor="middle" font-size="80" fill="#B4531F">${layout(a1d.count, a1d.spacing, a1d.firstEnd)}</text>`);
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(`<text x="${sx}" y="${sy - 40}" font-size="90" fill="#0F5C66">S2</text>`);
parts.push(`<text x="${sx + 200}" y="${sy + 150}" font-size="90" fill="#B4531F">S1</text>`);
parts.push(`<text x="0" y="${-800}" text-anchor="middle" font-size="90" fill="#18212B">${INTEGRATED_BLOCK.length}</text>`);
} 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(`<text x="${sx}" y="${sy}" font-size="90" fill="#0F5C66">S2</text>`);
parts.push(`<text x="${sx + 300}" y="${sy + 120}" font-size="90" fill="#B4531F">S1</text>`);
+7
View File
@@ -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
});
});