import type { PierModel } from '../core/geometry'; import { bearingEdgeDistances, pairEccentricities } from '../core/bearing-layout'; /** Number of pairs the 상세 보기 chips can show (①–⑩ in the mockup). */ export const PAIR_CHIP_LABELS = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩']; /** * 교량받침 상세 · 평면 for one pair (승인 2026-10-26): the bearings keep their actual 교각축 positions (the offset * between the two bearings is shown as it is), and the blocks and solplates follow them. 일체 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 교축. */ /** * A rectangle centred on (cx, cy), turned by the bearing's 방위 (승인 2026-10-26). The angle is −rowSkewDeg, the same * turn as the 3D block (rotateY(−skew)): the block's sides follow the bearing row. */ function rect(cx: number, cy: number, w: number, h: number, skewDeg: number, attrs: string): string { return ``; } export function bearingPlanSvg(m: PierModel, pairIndex: number): string { const pair = pairEccentricities(m.blocks)[pairIndex]; if (!pair) return ''; const f = m.blocks.find((b) => b.no === pair.frontNo && b.row === '전열')!; 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; // x: 교축 (n); y: 교각축 (s), the actual positions relative to the pair's mean. The offset is kept, not aligned. const X = (n: number) => (n - nc) * 1000; const Y = (s: number) => (s - sc) * 1000; const eccentricity = Math.abs(f.s - k.s) * 1000; const parts: string[] = []; // Axes: 교축 (horizontal, to the right) and 교각축 방향 (vertical, downward). parts.push(``); parts.push(``); parts.push(`교축`); parts.push(``); parts.push(``); parts.push(`교각축 방향`); // Block outline(s): one row. const ib = m.integratedBlocks.find((x) => x.frontNo === pair.frontNo); if (ib) { parts.push(rect(X(ib.n), Y(ib.s), 2500, 1200, ib.rowSkewDeg, `fill="none" stroke="#6E8496" stroke-width="12"`)); } else { for (const b of [f, k]) { parts.push(rect(X(b.n), Y(b.s), 1200, 1200, b.rowSkewDeg, `fill="none" stroke="#6E8496" stroke-width="12"`)); } } // Solplates: the pier's plan (L across the 교축, W along the 교각축), centred on each bearing. for (const b of [f, k]) { parts.push(rect(X(b.n), Y(b.s), b.plan.L, b.plan.W, b.rowSkewDeg, `fill="#EEF3F7" stroke="#2F6DB5" stroke-width="10"`)); } // Bearing centres and numbers. for (const b of [f, k]) { parts.push(``); parts.push(`${b.no} · 방위 ${b.rowSkewDeg.toFixed(2)}°`); } if (eccentricity > 0.5) { parts.push(`편심 ${eccentricity.toFixed(0)} mm (교각축 방향, 위치 그대로)`); } // 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)!; 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) => `${label}`; const y1 = 760; const y2 = 1000; // C1 and C2 are along the 교축 (horizontal), measured on the drawn positions. parts.push(dimLine(xLeft, X(f.n), y1, `C1 ${Math.round(X(f.n) - xLeft)}`)); 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(xRight - X(k.n))}`)); parts.push(dimLine(xLeft, xRight, y2, `C3 ${Math.round((xRight - xLeft))}`)); // C4 and C5 as in the 시안: vertical dimensions on the left of the blocks, from the top edge to the bearing row (C4) and // from the bearing row to the bottom edge (C5). Values: the model's C4 and C5 (outer margins). const xv = xLeft - 300; const halfDepth = 600; const vdim = (y1: number, y2: number, label: string) => `${label}`; // C4: from the low-side block edge to the front bearing; C5: from the back bearing to the high-side block edge. const lowEdge = ib ? Y(ib.s) - 600 : Y(f.s) - 600; const highEdge = ib ? Y(ib.s) + 600 : Y(k.s) + 600; parts.push(vdim(lowEdge, Y(f.s), `C4 ${Math.round(d(f.no).leftMm)}`)); parts.push(vdim(Y(k.s), highEdge, `C5 ${Math.round(d(k.no).rightMm)}`)); return `${parts.join('')}`; }