fix(world): Laternen vom Fahrbahnrand versetzt, ungenutzte Requisiten entfernt
Ruling 60: vergeLampPoints sucht von 6 bis 16 m nach außen und verwirft eine Laterne ganz, wenn keiner der sechs Abstände die Straßenpolygone des Chunks verlässt (Punkt-in-Polygon mit Löchern, pointInPolygon). Ruling 61: die vier nie platzierten Requisiten (Bank, Mülleimer, Hydrant, Absperrung) fliegen aus props.mjs und aus dem Repository, ~18 MB auf 1,9 MB im Arbeitsverzeichnis. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9173400caa
commit
d6a2f6d269
7 files changed
+120
-23
No files matched your search
+51
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { lampPoints, palmTransforms } from "../src/world/props.js";
|
||||
import { lampPoints, palmTransforms, pointInPolygon, vergeLampPoints } from "../src/world/props.js";
|
||||
|
||||
describe("props", () => {
|
||||
it("setzt Laternen im gewünschten Abstand entlang der Linie", () => {
|
||||
@@ -32,3 +32,53 @@ describe("props", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Fix-Runde 1, Befund A / Ruling 60: Laternen standen exakt auf der Mittellinie.
|
||||
describe("pointInPolygon", () => {
|
||||
// Quadrat 0..20 mit einem 4x4-Loch in der Mitte (8..12) — offene Ringe, wie im Rest
|
||||
// dieser Datei; die Laufzeitdaten schließen ihre Ringe (letzter Punkt = erster), das
|
||||
// Halbstrahl-Verfahren behandelt beide Formen gleich (siehe Kommentar in props.js).
|
||||
const outer = [[0, 0], [20, 0], [20, 20], [0, 20]];
|
||||
const hole = [[8, 8], [12, 8], [12, 12], [8, 12]];
|
||||
|
||||
it("Punkt innen (im Außenring, außerhalb jedes Lochs)", () => {
|
||||
expect(pointInPolygon(2, 2, [outer, hole])).toBe(true);
|
||||
});
|
||||
|
||||
it("Punkt außen (außerhalb des Außenrings)", () => {
|
||||
expect(pointInPolygon(25, 25, [outer, hole])).toBe(false);
|
||||
});
|
||||
|
||||
it("Punkt im Loch (im Außenring, aber auch im Loch)", () => {
|
||||
expect(pointInPolygon(10, 10, [outer, hole])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("vergeLampPoints", () => {
|
||||
it("versetzt eine Laterne von der Fahrbahn zum ersten freien Abstand, senkrecht zur Linie", () => {
|
||||
// angle 0 -> Blickrichtung (1, 0), Normale (0, 1). Straße 10 m breit (Halbbreite 5 m):
|
||||
// der erste Versatz aus LAMP_VERGE (6 m) reicht bereits über den Fahrbahnrand hinaus.
|
||||
const points = [{ x: 0, z: 0, angle: 0 }];
|
||||
const roads = [{ poly: [[[-50, -5], [50, -5], [50, 5], [-50, 5]]], bridge: false }];
|
||||
const out = vergeLampPoints(points, roads);
|
||||
expect(out).toHaveLength(1);
|
||||
expect(out[0].x).toBeCloseTo(0);
|
||||
expect(out[0].z).toBeCloseTo(6);
|
||||
expect(pointInPolygon(out[0].x, out[0].z, roads[0].poly)).toBe(false);
|
||||
});
|
||||
|
||||
it("lässt eine Laterne entfallen, wenn keiner der sechs Abstände die Fahrbahn verlässt", () => {
|
||||
// Halbbreite 20 m > größter Versatz (16 m) -> jede Probe bleibt auf der Fahrbahn.
|
||||
const points = [{ x: 0, z: 0, angle: 0 }];
|
||||
const roads = [{ poly: [[[-50, -20], [50, -20], [50, 20], [-50, 20]]], bridge: false }];
|
||||
expect(vergeLampPoints(points, roads)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("wechselt die Versatzseite von Punkt zu Punkt ab", () => {
|
||||
// Ohne Straßen gewinnt sofort der erste (kleinste) Versatz bei jedem Punkt.
|
||||
const points = [{ x: 0, z: 0, angle: 0 }, { x: 10, z: 0, angle: 0 }];
|
||||
const out = vergeLampPoints(points, []);
|
||||
expect(out[0].z).toBeCloseTo(6);
|
||||
expect(out[1].z).toBeCloseTo(-6);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user