Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
111 lines
3.5 KiB
JavaScript
111 lines
3.5 KiB
JavaScript
// 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건");
|