feat(bearing): plan with the blocks on one row, axis arrows, and C1·C2·C3 dimensions
- Blocks and solplates are drawn on one line across the 교축; the 교각축 offset of the bearings is written as text. - Arrows for the 교축 (horizontal) and the 교각축 방향 (vertical). - Dimensions along the bottom: C1 (bearing to block edge), C2 (between the bearings), C1, and C3 (block span). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0b847e7547
commit
da58fbfdbe
1 file changed
+39
-15
@@ -11,9 +11,10 @@ export interface BearingPlanOverlay {
|
||||
export const PAIR_CHIP_LABELS = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩'];
|
||||
|
||||
/**
|
||||
* 교량받침 상세 · 평면 for one pair (승인 2026-10-26): the model's solplates and blocks, with the drawing values overlaid
|
||||
* as dashed outlines when given. 일체 draws the pair's block as one outline (2500 across the 교축 × 1200 along the 교각축);
|
||||
* 분리 draws two 1200 × 1200 outlines. x is the 교축 (n), y the 교각축 (s, downward); units mm.
|
||||
* 교량받침 상세 · 평면 for one pair (승인 2026-10-26): the blocks and solplates are aligned in one row across the 교축
|
||||
* (x = n), with the actual 교각축 offset of the bearings written as text. The model's solplates are solid, the drawing values
|
||||
* dashed. 일체 draws one 2500 × 1200 outline; 분리 draws two 1200 × 1200 outlines. Dimensions: C1 (bearing to block edge),
|
||||
* C2 (between the bearings), C3 (block span). C4 and C5 are the outer margins along the 교축.
|
||||
*/
|
||||
export function bearingPlanSvg(m: PierModel, pairIndex: number, overlay?: BearingPlanOverlay): string {
|
||||
const pair = pairEccentricities(m.blocks)[pairIndex];
|
||||
@@ -22,18 +23,27 @@ export function bearingPlanSvg(m: PierModel, pairIndex: number, overlay?: Bearin
|
||||
const k = m.blocks.find((b) => b.no === pair.backNo && b.row === '후열')!;
|
||||
const nc = (f.n + k.n) / 2;
|
||||
const sc = (f.s + k.s) / 2;
|
||||
// The pair is drawn on one line: every block, solplate and bearing sits at the pair's mean 교각축 position.
|
||||
const X = (n: number) => (n - nc) * 1000;
|
||||
const Y = (s: number) => (s - sc) * 1000;
|
||||
const Y = (_s: number) => 0;
|
||||
const eccentricity = Math.abs(f.s - k.s) * 1000;
|
||||
const parts: string[] = [];
|
||||
|
||||
// Block outline(s): 일체 = one 2500 × 1200 outline; 분리 = two 1200 × 1200 outlines.
|
||||
// Axes: 교축 (horizontal, to the right) and 교각축 방향 (vertical, downward).
|
||||
parts.push(`<line x1="-1700" y1="0" x2="1650" y2="0" stroke="#B4531F" stroke-width="6" stroke-dasharray="120 60 20 60"></line>`);
|
||||
parts.push(`<polygon points="1650,0 1560,-40 1560,40" fill="#B4531F"></polygon>`);
|
||||
parts.push(`<text x="1640" y="-60" text-anchor="end" font-size="90" fill="#B4531F">교축</text>`);
|
||||
parts.push(`<line x1="0" y1="-900" x2="0" y2="900" stroke="#B4531F" stroke-width="6" stroke-dasharray="120 60 20 60"></line>`);
|
||||
parts.push(`<polygon points="0,-900 -40,-810 40,-810" fill="#B4531F"></polygon>`);
|
||||
parts.push(`<text x="60" y="-860" font-size="90" fill="#B4531F">교각축 방향</text>`);
|
||||
|
||||
// Block outline(s): one row.
|
||||
const ib = m.integratedBlocks.find((x) => x.frontNo === pair.frontNo);
|
||||
if (ib) {
|
||||
parts.push(`<rect x="${X(ib.n - 1.25)}" y="${Y(ib.s - 0.6)}" width="2500" height="1200" fill="none" stroke="#6E8496" stroke-width="12"></rect>`);
|
||||
parts.push(`<text x="${X(ib.n)}" y="${Y(ib.s - 0.6) - 60}" text-anchor="middle" font-size="90" fill="#55606E">C3 2500 (일체 블록 윤곽)</text>`);
|
||||
parts.push(`<rect x="${X(ib.n - 1.25)}" y="-600" width="2500" height="1200" fill="none" stroke="#6E8496" stroke-width="12"></rect>`);
|
||||
} else {
|
||||
for (const b of [f, k]) {
|
||||
parts.push(`<rect x="${X(b.n) - 600}" y="${Y(b.s) - 600}" width="1200" height="1200" fill="none" stroke="#6E8496" stroke-width="12"></rect>`);
|
||||
parts.push(`<rect x="${X(b.n) - 600}" y="-600" width="1200" height="1200" fill="none" stroke="#6E8496" stroke-width="12"></rect>`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,25 +54,39 @@ export function bearingPlanSvg(m: PierModel, pairIndex: number, overlay?: Bearin
|
||||
parts.push(`<rect x="${X(b.n) - A / 2}" y="${Y(b.s) - B / 2}" width="${A}" height="${B}" fill="#EEF3F7" stroke="#2F6DB5" stroke-width="10"></rect>`);
|
||||
}
|
||||
}
|
||||
// Drawing values overlaid (dashed red) on the same bearings (#1 겹쳐 보이게).
|
||||
// Drawing values overlaid (dashed) on the same bearings (#1 겹쳐 보이게).
|
||||
if (overlay) {
|
||||
for (const [b, v] of [[f, overlay.front], [k, overlay.back]] as const) {
|
||||
parts.push(`<rect x="${X(b.n) - v.A / 2}" y="${Y(b.s) - v.B / 2}" width="${v.A}" height="${v.B}" fill="none" stroke="#B4531F" stroke-width="10" stroke-dasharray="40 25"></rect>`);
|
||||
}
|
||||
}
|
||||
|
||||
// Bearing centres and labels.
|
||||
// Bearing centres and numbers.
|
||||
for (const b of [f, k]) {
|
||||
parts.push(`<circle cx="${X(b.n)}" cy="${Y(b.s)}" r="40" fill="#18212B"></circle>`);
|
||||
parts.push(`<text x="${X(b.n) + 70}" y="${Y(b.s) - 60}" font-size="90" fill="#18212B">${b.no}</text>`);
|
||||
}
|
||||
if (eccentricity > 0.5) {
|
||||
parts.push(`<text x="0" y="${-700}" text-anchor="middle" font-size="80" fill="#55606E">편심 ${eccentricity.toFixed(0)} mm (교각축 방향, 블록은 한 줄로 맞춤)</text>`);
|
||||
}
|
||||
|
||||
// Dimensions: C2 between the bearing centres, C4 and C5 from the bearing to the block edges (교축).
|
||||
// Dimensions along the bottom: C1 (bearing to block edge), C2 (between the bearings), C1, and C3 (block span).
|
||||
const dist = bearingEdgeDistances(m);
|
||||
const d = (no: number) => dist.find((x) => x.no === no)!;
|
||||
parts.push(`<text x="${(X(f.n) + X(k.n)) / 2}" y="${Y(f.s) + 180}" text-anchor="middle" font-size="90" fill="#18212B">C2 ${Math.round(Math.abs(k.n - f.n) * 1000)}</text>`);
|
||||
parts.push(`<text x="${X(f.n) - 760}" y="${Y(f.s)}" text-anchor="end" font-size="90" fill="#18212B">C4 ${Math.round(d(f.no).leftMm ?? 0)}</text>`);
|
||||
parts.push(`<text x="${X(k.n) + 760}" y="${Y(k.s)}" font-size="90" fill="#18212B">C5 ${Math.round(d(k.no).rightMm ?? 0)}</text>`);
|
||||
const xLeft = ib ? X(ib.n - 1.25) : X(f.n) - 600;
|
||||
const xRight = ib ? X(ib.n + 1.25) : X(k.n) + 600;
|
||||
const dimLine = (x1: number, x2: number, y: number, label: string) =>
|
||||
`<line x1="${x1}" y1="${y}" x2="${x2}" y2="${y}" stroke="#55606E" stroke-width="6"></line><line x1="${x1}" y1="${y - 50}" x2="${x1}" y2="${y + 50}" stroke="#55606E" stroke-width="6"></line><line x1="${x2}" y1="${y - 50}" x2="${x2}" y2="${y + 50}" stroke="#55606E" stroke-width="6"></line><text x="${(x1 + x2) / 2}" y="${y + 110}" text-anchor="middle" font-size="90" fill="#18212B">${label}</text>`;
|
||||
const y1 = 760;
|
||||
const y2 = 1000;
|
||||
parts.push(dimLine(xLeft, X(f.n), y1, `C1 ${Math.round(d(f.no).leftMm ?? 600)}`));
|
||||
parts.push(dimLine(X(f.n), X(k.n), y1, `C2 ${Math.round(Math.abs(k.n - f.n) * 1000)}`));
|
||||
parts.push(dimLine(X(k.n), xRight, y1, `C1 ${Math.round(d(k.no).rightMm ?? 600)}`));
|
||||
parts.push(dimLine(xLeft, xRight, y2, `C3 ${Math.round((xRight - xLeft))}`));
|
||||
|
||||
return `<svg viewBox="-1800 -1000 3600 2000" width="100%" style="max-width: 560px; height: auto" role="img" aria-label="교량받침 상세 평면: 쌍 ${pair.frontNo}·${pair.backNo}, 블록 윤곽, 솔플레이트, 도면값 겹쳐 보기">${parts.join('')}</svg>`;
|
||||
// C4 and C5: the outer margins along the 교축, shown at the outer block edges.
|
||||
parts.push(`<text x="${xLeft - 60}" y="-60" text-anchor="end" font-size="90" fill="#18212B">C4 ${Math.round(d(f.no).leftMm ?? 0)}</text>`);
|
||||
parts.push(`<text x="${xRight + 60}" y="-60" font-size="90" fill="#18212B">C5 ${Math.round(d(k.no).rightMm ?? 0)}</text>`);
|
||||
|
||||
return `<svg viewBox="-1900 -1300 3800 2600" width="100%" style="max-width: 560px; height: auto" role="img" aria-label="교량받침 상세 평면: 쌍 ${pair.frontNo}·${pair.backNo}, 블록 한 줄, 교축·교각축 방향, C1·C2·C3, C4·C5, 도면값 겹쳐 보기">${parts.join('')}</svg>`;
|
||||
}
|
||||
Reference in new issue
Block a user