Westpodest, Osttreppe, Gartenschrank, Start in der Uebersicht
Deploy App / deploy (push) Successful in 27s

- Weg um das Haus: der westliche Arm fehlte. Vor dem Gartentor liegt
  jetzt ein Podest auf -0.14 (Plan: dreimal -0.14 bis zur Suedwestecke),
  das an der Ecke in den Weg entlang der Suedgrenze uebergeht. Gegen die
  tiefer liegende Feuerwehrzufahrt schliesst ein Betonabschluss ab.
- Westtreppe gedreht: die Trittlinien liegen im Plan parallel zur Rinne,
  die Treppe laeuft also laengs der Grenze nach Norden, vom Podest auf die
  Feuerwehrzufahrt (-0.14 auf -1.08). Die Zufahrt ist dort ausgespart.
- Osttreppe war unter Rasen verschwunden. Unter Treppen wird das Gelaende
  jetzt unter die unterste Trittkante gelegt; die Treppe reicht vom
  Gelaender bis an die Winkelelemente. Der Belagstreifen, der sie
  zugedeckt hatte, ist weg.
- Belaege und feste Ebenen legen das Gelaende auch ausserhalb der Zonen
  fest. Vorher stand am Fuss der Osttreppe ein Grashuegel ueber dem
  Podest. Podest und Stellplatte liegen gemeinsam auf -1.57.
- Gartenschrank um 90 Grad gedreht: Rueckwand zum Beerenbeet, Doppeltueren
  zum Hauszugang. Dunkler gebeizt, damit er nicht mit der Fassade
  verschmilzt.
- Schwebender Travertinblock an der Nordwestecke entfernt.
- Die App oeffnet im Uebersichtsmodus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-13 09:21:46 +02:00
co-authored by Claude Opus 5
parent fefa8e8c9a
commit 866bedf64d
5 changed files with 84 additions and 37 deletions
+41 -14
View File
@@ -389,25 +389,52 @@ for (let j = 0; j < nz; j++) {
y = interpolate(x, z, best.id);
} else {
y = interpolate(x, z, zone);
// Ausdruecklich flach vorgegebene Ebenen: der Rasen der oberen Ebene
// ist eben, ohne Vorgabe zieht ihn die Interpolation huegelig hoch.
for (const lv of LEVELS) {
if (!lv.flatten || !pointInPolygon(x, z, lv.polygon)) continue;
y = lv.level;
locked[j * nx + i] = 1;
break;
}
for (const f of flatSurfaces) {
if (!pointInPolygon(x, z, f.polygon)) continue;
y = Math.max(f.min, Math.min(f.max, f.plane.a * x + f.plane.b * z + f.plane.c));
locked[j * nx + i] = 1;
break;
}
}
// Feste Ebenen und Belaege gelten auch ausserhalb der Zonen. Vorher
// griffen sie nur innerhalb - das Podest am Fuss der Osttreppe liegt
// aber zwischen den Zonen, und dort stand ein Grashuegel darueber.
for (const lv of LEVELS) {
if (!lv.flatten || !pointInPolygon(x, z, lv.polygon)) continue;
y = lv.level;
locked[j * nx + i] = 1;
break;
}
for (const f of flatSurfaces) {
if (!pointInPolygon(x, z, f.polygon)) continue;
y = Math.max(f.min, Math.min(f.max, f.plane.a * x + f.plane.b * z + f.plane.c));
locked[j * nx + i] = 1;
break;
}
height[j * nx + i] = y;
}
}
// Unter den Treppen muss das Gelaende unter der untersten Trittkante liegen.
// Sonst waechst die Boeschung durch die Blockstufen hindurch und die Treppe
// verschwindet unter Rasen - genau das war an der Osttreppe passiert.
for (const f of LINEAR) {
if (f.kind !== 'treppe') continue;
const [ax, az] = f.path[0], [bx, bz] = f.path[f.path.length - 1];
const len = Math.hypot(bx - ax, bz - az) || 1;
const ux = (bx - ax) / len, uz = (bz - az) / len;
const riser = (f.fromY - f.toY) / f.steps;
const half = f.width / 2 + 0.08;
for (let j = 0; j < nz; j++) {
const z = GRID.z0 + j * CELL;
for (let i = 0; i < nx; i++) {
const x = GRID.x0 + i * CELL;
const s = (x - ax) * ux + (z - az) * uz;
const q = -(x - ax) * uz + (z - az) * ux;
if (s < -0.1 || s > len + 0.1 || Math.abs(q) > half) continue;
const t = Math.max(0, Math.min(1, s / len));
const unter = f.fromY + (f.toY - f.fromY) * t - riser - 0.03;
const k = j * nx + i;
height[k] = Math.min(height[k], unter);
locked[k] = 1;
}
}
}
// Glaetten - aber nur die freien Felder. Die Belaege bleiben exakt eben.
let smoothed = Float32Array.from(height);
for (let pass = 0; pass < 3; pass++) {