// B07 CAD 수확 — pattern 채움(노면공 무늬 셋 · 물넘이 빗금)을 다각형 안 선 · 원으로 펴기(88-4). // 실제 코드(`B07_DesignDetail_Cross_Overlay.patternMarks`)를 vite ssr 로 묶어 돌린다. // 실행: node resources/tester/test_cad_pattern_harvest.mjs import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { pathToFileURL } from "node:url"; const ROOT = resolve(import.meta.dirname, "../.."); const out = mkdtempSync(join(tmpdir(), "cad-pattern-")); execFileSync( "node", [ "./config/node_modules/vite/bin/vite.js", "build", "--configLoader", "runner", "--ssr", "../B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts", "--outDir", out, "--logLevel", "error", ], { cwd: ROOT, stdio: "pipe" }, ); const { patternMarks } = await import( pathToFileURL(join(out, "B07_DesignDetail_Cross_Overlay.js")).href ); // 도면 좌표(y 위로) 다각형 — SVG y 100~103(두께 3) · x 10~70. 닫힌 점열. const polygon = [ [10, -100], [70, -100], [70, -103], [10, -103], [10, -100], ]; const inPoly = ([x, y]) => x >= 10 - 1e-6 && x <= 70 + 1e-6 && y <= -100 + 1e-6 && y >= -103 - 1e-6; const allPoints = (marks) => [ ...marks.polylines.flat(), ...marks.circles.flatMap(({ center: [cx, cy], radius }) => [ [cx - radius, cy], [cx + radius, cy], [cx, cy - radius], [cx, cy + radius], ]), ]; // ① 콘크리트 · 물넘이 빗금(M0,6 L6,0 · 칸 6) — 대각선이 칸을 넘어 이어져 한 줄씩 · 모두 다각형 안 { const marks = patternMarks(polygon, { width: 6, height: 6, paths: [ [ [0, 6], [6, 0], ], ], rings: [], }); assert.equal(marks.circles.length, 0); // x+y = 6k 인 대각선 중 띠(y 100~103)를 지나는 것: x+y ∈ (110, 173) → k = 19..28 = 10 줄 assert.equal(marks.polylines.length, 10, `빗금 줄 수 ${marks.polylines.length}`); for (const run of marks.polylines) assert.equal(run.length, 2, "한 줄 = 두 점(이어 붙임)"); assert.ok(allPoints(marks).every(inPoly), "빗금이 다각형 밖으로 나감"); } // ② 아스콘 점(원 r 0.7 · 칸 5) — 온전히 든 원은 원 그대로 { const marks = patternMarks(polygon, { width: 5, height: 5, paths: [], rings: [{ cx: 1.5, cy: 1.5, rx: 0.7, ry: 0.7 }], }); // 중심 y = 101.5 (칸 j=20) · x = 11.5, 16.5 … 66.5 = 12 개 — 모두 띠 안 assert.equal(marks.circles.length, 12, `점 수 ${marks.circles.length}`); assert.equal(marks.polylines.length, 0); assert.ok(allPoints(marks).every(inPoly), "점이 다각형 밖으로 나감"); } // ③ 쇄석 돌(원 r 1.6 + 타원 · 칸 9) — 걸친 것은 잘린 폴리선 · 밖으로 안 나감 { const marks = patternMarks(polygon, { width: 9, height: 9, paths: [], rings: [ { cx: 2.5, cy: 2.5, rx: 1.6, ry: 1.6 }, { cx: 6.8, cy: 6.5, rx: 1.8, ry: 1.2 }, ], }); assert.ok(marks.polylines.length + marks.circles.length > 0, "돌 무늬 없음"); assert.ok(allPoints(marks).every(inPoly), "돌이 다각형 밖으로 나감"); } // ④ 빈 칸 · 다각형 없음 = 무늬 없음 { assert.deepEqual(patternMarks(polygon, { width: 0, height: 6, paths: [], rings: [] }), { polylines: [], circles: [], }); assert.equal(patternMarks([], { width: 6, height: 6, paths: [], rings: [] }).polylines.length, 0); } console.log("OK test_cad_pattern_harvest.mjs — 4건");