From 6050435af181ab90d5e3c7bff4b317e04bd1ac44 Mon Sep 17 00:00:00 2001 From: ypshim Date: Fri, 23 Oct 2026 16:14:08 +0900 Subject: [PATCH] =?UTF-8?q?feat(view):=20dimension=20lines=20on=20the=20?= =?UTF-8?q?=EC=A0=95=EB=A9=B4=20=E2=80=94=20footing=20length=20above,=20h1?= =?UTF-8?q?=20at=20the=20right,=20the=20visible=20pile=20length=20at=20the?= =?UTF-8?q?=20left?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The side view has dimension lines with 45° ticks: the footing length (mm) above the footing, the footing height h1 at its right, and the visible pile length (끊음) at its left. The margins are wider (1.5 m) for the labels; the plan uses the same margin so the two views stay aligned. The old h1 label is replaced by the dimension label. Co-Authored-By: Claude Haiku 5.5 --- src/view/footing-svg.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/view/footing-svg.ts b/src/view/footing-svg.ts index 84b4674..7cbfa5e 100644 --- a/src/view/footing-svg.ts +++ b/src/view/footing-svg.ts @@ -13,6 +13,18 @@ const PILE_STUB = 4; const mm = (v: number) => Math.round(v * 1000); +/** Horizontal dimension line from x1 to x2 at height y, with 45° ticks and a centred label above it (승인 2026-10-23). */ +function dimH(x1: number, x2: number, y: number, label: string): string { + const t = 0.12; + return `${label}`; +} + +/** Vertical dimension line from y1 to y2 at x, with 45° ticks and the label to its right. */ +function dimV(x: number, y1: number, y2: number, label: string): string { + const t = 0.12; + return `${label}`; +} + /** A break mark (끊음): two short slanted strokes "//" centred on (x, y), so the member is shown as cut. */ function breakMark(x: number, y: number, halfWidth: number): string { const d = 0.12; @@ -29,7 +41,7 @@ function svgOf(x0: number, y0: number, w: number, h: number, label: string, body export function footingPlanSvg(model: PierModel): string { const f = model.footings[0]; if (!f) return ''; - const pad = 0.8; + const pad = 1.5; const x0 = f.s - f.length / 2 - pad; const y0 = -f.width / 2 - pad; const w = f.length + 2 * pad; @@ -56,7 +68,7 @@ export function footingSideSvg(model: PierModel): string { const piles = model.piles.filter((p) => Math.abs(p.s - f.s) <= f.length / 2 + 1e-6); const pileTop = piles.length ? Math.max(...piles.map((p) => p.top)) : f.bottom; const pileLen = piles.length ? piles[0].top - piles[0].bottom : 0; - const pad = 0.8; + const pad = 1.5; const x0 = f.s - f.length / 2 - pad; const w = f.length + 2 * pad; // Visible band in EL: from the column stub above the footing top, down to the pile stub below the footing bottom. @@ -81,10 +93,15 @@ export function footingSideSvg(model: PierModel): string { // Break mark across the pile group, in the lower stub (the pile label sits below it). parts.push(breakMark(f.s, -(botEl + 0.6), f.length / 2)); } - parts.push(`h1 ${mm(f.top - f.bottom)}`); if (piles.length) { parts.push(`말뚝 ${mm(pileLen)} (끊음)`); } + // Dimension lines (치수선): footing length above, footing height at the right, the visible pile length at the left. + parts.push(dimH(f.s - f.length / 2, f.s + f.length / 2, -(f.top + 0.8), `${mm(f.length)}`)); + parts.push(dimV(f.s + f.length / 2 + 0.5, -f.top, -f.bottom, `h1 ${mm(f.top - f.bottom)}`)); + if (piles.length) { + parts.push(dimV(f.s - f.length / 2 - 0.5, -f.bottom, -(botEl + 0.6), `${mm(pileLen)} (끊음)`)); + } void pileTop; return svgOf(x0, y0, w, h, '확대기초·말뚝 측면', parts.join('')); }