Files
Gartenvisualisierung/tools/inspect-heights.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

17 lines
1.3 KiB
JavaScript

import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const d = JSON.parse(fs.readFileSync(path.join(__dirname,'out','plan-raw.json'),'utf8'));
console.log('--- Hoehenkoten (x, z, y) sortiert nach y ---');
for (const s of [...d.spots].sort((a,b)=>a.y-b.y))
console.log(String(s.y.toFixed(2)).padStart(6), ' x='+String(s.x.toFixed(2)).padStart(7), ' z='+String(s.z.toFixed(2)).padStart(7));
function inside(pt, poly){let c=false;for(let i=0,j=poly.length-1;i<poly.length;j=i++){const [xi,zi]=poly[i],[xj,zj]=poly[j];if((zi>pt[1])!==(zj>pt[1])&&pt[0]<(xj-xi)*(pt[1]-zi)/(zj-zi)+xi)c=!c;}return c;}
console.log('\n--- Hoehenkoten je grosse Flaeche ---');
const big = d.shapes.filter(s=>s.op==='f'&&s.area>=1.0&&s.hex!=='#000000').sort((a,b)=>b.area-a.area);
for(const s of big){
const hits = d.spots.filter(sp=>inside([sp.x,sp.z], s.pts));
const nearby = d.spots.filter(sp=>!inside([sp.x,sp.z],s.pts)).map(sp=>({sp,dd:Math.min(...s.pts.map(p=>Math.hypot(p[0]-sp.x,p[1]-sp.z)))})).filter(o=>o.dd<0.6).map(o=>o.sp);
console.log(s.hex, String(s.area.toFixed(1)).padStart(6)+'m2',
'innen=['+hits.map(h=>h.y.toFixed(2)).join(' ')+']',
'rand=['+nearby.map(h=>h.y.toFixed(2)).join(' ')+']');
}