docs: Laternen nicht mehr auf die Kreuzung setzen (Ruling 18)
Seit Task 4 sind die Mittellinien an Kreuzungen getrennt. lampPoints startete bei Streckenlänge 0 und setzte damit je einmündendem Ast eine Laterne in denselben Punkt, mitten auf die Fahrbahn. Start jetzt bei halber Teilung, dazu ein Test, der das Stapeln nachweist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
dce90a2263
commit
4c82b14a57
1 file changed
+22
-5
@@ -2427,12 +2427,22 @@ import { lampPoints, palmTransforms } from "../src/world/props.js";
|
||||
describe("props", () => {
|
||||
it("setzt Laternen im gewünschten Abstand entlang der Linie", () => {
|
||||
const pts = lampPoints([[[0, 0], [100, 0]]], 35);
|
||||
expect(pts.length).toBe(3); // 0, 35, 70 Meter
|
||||
expect(pts[1].x).toBeCloseTo(35);
|
||||
expect(pts.length).toBe(3); // 17,5 / 52,5 / 87,5 Meter
|
||||
expect(pts[0].x).toBeCloseTo(17.5); // nicht auf der Kreuzung
|
||||
expect(pts[1].x).toBeCloseTo(52.5);
|
||||
});
|
||||
|
||||
it("ignoriert zu kurze Linien", () => {
|
||||
expect(lampPoints([[[0, 0], [10, 0]]], 35)).toHaveLength(1);
|
||||
it("setzt auf einer kurzen Linie eine Laterne in die Mitte", () => {
|
||||
const pts = lampPoints([[[0, 0], [10, 0]]], 35);
|
||||
expect(pts).toHaveLength(1);
|
||||
expect(pts[0].x).toBeCloseTo(5);
|
||||
});
|
||||
|
||||
it("stapelt an einer Kreuzung keine Laternen", () => {
|
||||
// Zwei gegenüberliegende Äste, wie centerlines() sie seit Task 4 liefert.
|
||||
const pts = lampPoints([[[0, 0], [60, 0]], [[0, 0], [-60, 0]]], 35);
|
||||
const keys = new Set(pts.map((p) => `${p.x.toFixed(2)},${p.z.toFixed(2)}`));
|
||||
expect(keys.size).toBe(pts.length);
|
||||
});
|
||||
|
||||
it("skaliert Palmen reproduzierbar zwischen 10 und 18 Metern", () => {
|
||||
@@ -2473,7 +2483,14 @@ function hashUnit(seed, key) {
|
||||
export function lampPoints(lines, spacing = 35) {
|
||||
const out = [];
|
||||
for (const line of lines) {
|
||||
let travelled = 0, next = 0;
|
||||
let total = 0;
|
||||
for (let i = 0; i < line.length - 1; i++) {
|
||||
total += Math.hypot(line[i + 1][0] - line[i][0], line[i + 1][1] - line[i][1]);
|
||||
}
|
||||
// Erste Laterne bei halber Teilung: die Mittellinien sind an Kreuzungen getrennt,
|
||||
// ein Start bei 0 setzt je einmündendem Ast eine Laterne in denselben Punkt —
|
||||
// an einer Kreuzung mit vier Ästen also vier, mitten auf der Fahrbahn.
|
||||
let travelled = 0, next = Math.min(spacing / 2, total / 2);
|
||||
for (let i = 0; i < line.length - 1; i++) {
|
||||
const [x0, z0] = line[i], [x1, z1] = line[i + 1];
|
||||
const len = Math.hypot(x1 - x0, z1 - z0);
|
||||
|
||||
Reference in new issue
Block a user