Files
Gartenvisualisierung/tools/inspect-colors.mjs
T
admGitAICDSandClaude Opus 5 70d239fe9c Begehbare 3D-Visualisierung des Gartens Egglihaldenstrasse 9a
Geometrie massstaeblich aus dem Gartenplan-PDF (1:100) extrahiert: Belaege,
Mauern, Pflanzenstandorte und 46 Hoehenkoten. Wohnhaus nach Gartenplan und
den Fassadenplaenen von EHLE Architekten.

- tools/: Pipeline PDF -> Szenenmodell (MuPDF, Node)
- src/: three.js-Szene mit prozeduralen Texturen, Rundgang und Uebersicht
- Docker/Traefik fuer garten.aicds.ch, Gitea-Workflow auf main

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 22:59:37 +02:00

53 lines
1.7 KiB
JavaScript

/**
* Listet alle Fuellfarben des Plans mit Flaeche, Anzahl Polygone und den
* naechstgelegenen Beschriftungen - Grundlage fuer die Farb-zu-Material-Zuordnung.
*
* Aufruf: node tools/inspect-colors.mjs [minFlaeche]
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const data = JSON.parse(fs.readFileSync(path.join(__dirname, 'out', 'plan-raw.json'), 'utf8'));
const MIN = parseFloat(process.argv[2] ?? '0.15');
const centroid = (pts) => {
let x = 0, z = 0;
for (const p of pts) { x += p[0]; z += p[1]; }
return [x / pts.length, z / pts.length];
};
const groups = new Map();
for (const s of data.shapes) {
if (s.op !== 'f') continue;
const g = groups.get(s.hex) ?? { hex: s.hex, n: 0, area: 0, big: [], circles: 0 };
g.n++; g.area += s.area;
if (s.circle) g.circles++;
if (s.area >= MIN) g.big.push(s);
groups.set(s.hex, g);
}
const rows = [...groups.values()].sort((a, b) => b.area - a.area);
for (const g of rows) {
if (g.area < 0.2 && g.circles === 0) continue;
const near = new Set();
for (const s of g.big.slice(0, 6)) {
const [cx, cz] = centroid(s.pts);
const cands = data.labels
.map((l) => ({ l, d: Math.hypot(l.x - cx, l.z - cz) }))
.filter((c) => c.d < 3.5 && !/^-?\d\.\d{2}$/.test(c.l.text))
.sort((a, b) => a.d - b.d)
.slice(0, 3);
for (const c of cands) near.add(c.l.text);
}
console.log(
g.hex.padEnd(9),
('n=' + g.n).padEnd(7),
(g.area.toFixed(1) + ' m2').padStart(9),
('gross=' + g.big.length).padEnd(10),
('kreise=' + g.circles).padEnd(11),
[...near].slice(0, 7).join(' / '),
);
}