Linien-/Random-Editor: Strich-Segmente, Vollinie, Random-Kontrollen; Weight raus

Linien-Editor: Umschalter Vollinie (dash null) / Strich mit editierbarer
Segment-Liste (mm, alternierend Strich/Luecke, hinzufuegen/entfernen), Live-
Vorschau. Das Strichstaerken-Feld ist aus dem Linien-Editor entfernt —
LineStyle.weight ist @deprecated (bleibt Render-Fallback), die echte
per-Element-Aufloesung (Attribut->Ebene->Default) folgt separat.

Random-Schraffur: additive HatchStyle-Parameter seed/density/lengthMin/Max +
Neu-wuerfeln-Button (neuer Seed nur zur Editzeit). buildRandomHatchRuns mischt
den expliziten Seed in den Hash und nutzt Dichte/Laenge — Determinismus
gewahrt (gleicher Seed+Flaeche => gleiche Streuung), ueber alle Renderpfade
konsistent, da alle aus derselben Funktion ziehen. resolveHatch/HatchRender
reichen die Parameter rein additiv durch. 2 neue Tests.
This commit is contained in:
2026-07-04 00:53:19 +02:00
parent 87ef7988d1
commit 07475cbe6c
8 changed files with 248 additions and 54 deletions
+19
View File
@@ -68,6 +68,25 @@ describe("Random-Vektor-Schraffur", () => {
expect(JSON.stringify(random)).not.toEqual(JSON.stringify(parallel));
});
it("expliziter Seed ist reproduzierbar und aendert die Streuung (Neu wuerfeln)", () => {
const base = { kind: "vector", lines: "random", scale: 1 } as const;
const s7a = buildHatchRuns(SQUARE, hatch({ ...base, seed: 7 }));
const s7b = buildHatchRuns(SQUARE, hatch({ ...base, seed: 7 }));
const s8 = buildHatchRuns(SQUARE, hatch({ ...base, seed: 8 }));
expect(s7a).toEqual(s7b); // gleicher Seed ⇒ identische Geometrie
expect(JSON.stringify(s7a)).not.toEqual(JSON.stringify(s8)); // neuer Seed ⇒ neue Streuung
});
it("Dichte verdichtet die Streuung, Längenspanne wird angewandt", () => {
const base = { kind: "vector", lines: "random", scale: 1, seed: 3 } as const;
const sparse = buildHatchRuns(SQUARE, hatch({ ...base }));
const dense = buildHatchRuns(SQUARE, hatch({ ...base, density: 3 }));
expect(dense.length).toBeGreaterThan(sparse.length);
// Längenspanne greift ohne zu werfen und bleibt deterministisch.
const ranged = buildHatchRuns(SQUARE, hatch({ ...base, lengthMin: 1, lengthMax: 2 }));
expect(ranged).toEqual(buildHatchRuns(SQUARE, hatch({ ...base, lengthMin: 1, lengthMax: 2 })));
});
it("erscheint als Streu-Polylinien in der RenderScene (deterministisch)", () => {
const poly: Primitive = {
kind: "polygon",