From 65d6e843fbe074755880f8cfe89682e467c6c71f Mon Sep 17 00:00:00 2001 From: Karim Date: Sat, 4 Jul 2026 14:22:12 +0200 Subject: [PATCH] Fix Regression: 3D-Wandschichten auf linke Normale (Schnitt = Grundriss) de7a26b versetzte die per-Schicht-Boxen entlang (uy,-ux) = RECHTE Normale, waehrend Grundriss/clippedBand die LINKE Normale leftNormal(u)=(-uy,ux) nutzt -> Schichten im 3D UND im davon abgeleiteten 2D-Schnitt gespiegelt (Backstein aussen statt innen). pushSegment nutzt jetzt die linke Normale. Wandlage unveraendert (Stack bleibt symmetrisch um die Achse), nur die Schichtseiten stimmen wieder mit dem Grundriss. raycast3d unberuehrt (symmetrische Box). 216 Tests gruen, kein WASM-Rebuild. --- src/plan/toWalls3d.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plan/toWalls3d.ts b/src/plan/toWalls3d.ts index 9d8eec3..1614ea5 100644 --- a/src/plan/toWalls3d.ts +++ b/src/plan/toWalls3d.ts @@ -237,12 +237,19 @@ function pushSegment( if (len < 1e-9) return; const ux = dx / len; const uy = dy / len; - // Grundriss-Normale (identisch zur Dicken-Achse in raycast3d / - // selectionHighlightLines: n = (uy, −ux)). Der Schicht-Versatz verschiebt - // Start/Ende der Box quer zur Wand, sodass render3d/raycast die Box um ihre - // eigene (versetzte) Achse zentriert aufbaut. - const ox = uy * normalOffset; - const oy = -ux * normalOffset; + // LINKE Grundriss-Normale (identisch zu `leftNormal(u)` = (−uy, ux) in + // generatePlan.ts/clippedBand — dieselbe Konvention, die addWallPoche für + // den Schichtstapel im 2D-Grundriss benutzt). Der Schicht-Versatz verschiebt + // Start/Ende der Box quer zur Wand, sodass render3d die Box um ihre eigene + // (versetzte) Achse zentriert aufbaut — mit dieser Normale liegt Schicht 0 + // (Aussenseite, kleinster `offset`) auf derselben Weltseite wie im Grundriss. + // Bewusst NICHT identisch zur Normale, die raycast3d/selectionHighlightLines + // für den Box-Rebuild nutzen (n = (uy, −ux), rechte Normale) — das ist + // unschädlich, weil jene Boxen symmetrisch um die (hier bereits versetzte) + // Achse jedes einzelnen Layer-Records aufgebaut werden und daher unabhängig + // von der Vorzeichen-Konvention des Versatzes sind. + const ox = -uy * normalOffset; + const oy = ux * normalOffset; const p1: RVec2 = [wall.start.x + ux * from + ox, wall.start.y + uy * from + oy]; const p2: RVec2 = [wall.start.x + ux * to + ox, wall.start.y + uy * to + oy]; out.push({