/** * 솔플레이트 기하 (승인 2026-10-23). Pure: the solplate of one bearing, from its block (position, rowSkew) and the * 공통 규칙 values. The plan is L = A + margin across the 교각축 직각 (n) and W = B + margin along the 교축 (s). The top * tapers across L: the thick end T1 is at the (−) side of the 교각축 직각 direction (n = −L/2), the thin end T2 at (+) (n = +L/2). * The underside is the bearing top (block top EL.X + h3). Lengths in m, as in the model. */ import { blockFramePoint, type BlockModel } from './geometry'; export interface SolplateParams { /** 받침 평면 A (mm, across the 교각축 직각) and B (mm, along the 교축). */ A: number; B: number; /** 솔플 여유 (mm): L = A + margin, W = B + margin. */ margin: number; /** 중심 두께 T (mm). */ T: number; /** 기울기 S (%), negative as drawn: thickness changes by L·|S|/2 from the centre. */ slopePct: number; } export interface SolplateGeometry { /** Length across the 교각축 직각 (m, = A + margin) and width along the 교축 (m, = B + margin). */ L: number; W: number; /** Thickness at the (−) side (T1) and the (+) side (T2) of the 교각축 직각 direction (m). */ T1: number; T2: number; /** Underside (EL m): the bearing top = block top (EL.X) + h3. */ bottom: number; /** Eight corners: [s, y, n] in the model's local frame (EL m); order (a, c, bottom|top) with a along s and c along n. */ corners: [number, number, number][]; /** Volume (m³): L·W·(T1 + T2)/2. */ volume: number; } /** Solplate of the bearing at `block`, with the bearing height h3 (mm) and the 공통 규칙 parameters. */ export function solplateGeometry(block: BlockModel, h3: number, p: SolplateParams): SolplateGeometry { const L = (p.A + p.margin) / 1000; // across the 교각축 직각 (n) const W = (p.B + p.margin) / 1000; // along the 교축 (s) // Thickness change from the centre to each side: L·|S|/2, with S in % (mm). const drop = ((p.A + p.margin) * Math.abs(p.slopePct)) / 200 / 1000; const T = p.T / 1000; const T1 = T + drop; const T2 = T - drop; const bottom = block.padTop + h3 / 1000; const thickAt = (c: number) => T1 + ((T2 - T1) * (c + L / 2)) / L; const corners: [number, number, number][] = []; for (const a of [-W / 2, W / 2]) { for (const c of [-L / 2, L / 2]) { const [s, n] = blockFramePoint(block, a, c); corners.push([s, bottom, n]); corners.push([s, bottom + thickAt(c), n]); } } return { L, W, T1, T2, bottom, corners, volume: (L * W * (T1 + T2)) / 2 }; }