test: U-Form-Faelle, Formkriterium laengs und Reihenanordnung der Linienzug-Tests

Drei neue Modus-2-Testfaelle aus echten Laeufen, ein Kriterium, das eine
heute eingebaute Fehlgeometrie gefunden haette, und ein aufgeraeumtes
Layout der Testketten.

1. Drei U-Form-Faelle (tests/testdata/linienzug_modus2_uform_*.json),
   aufgezeichnet mit lib/vf_journal_export.py. Gefaltete Laeufe: der Pfad
   wechselt ueber zwei 90-Grad-Vario-Kurven dreimal die Fahrtrichtung, die
   Kletterstrecke liegt in einem ANDEREN Schenkel als der Lauf-Eingang -
   genau der am 2026-10-29 korrigierte Fall. Variiert werden GF-Verteilung
   (alles am Einlauf vs. 1/2+1/2) und Winkel; beides ist noetig, weil die
   Verteilung entscheidet, ob ueberhaupt GF im fremden Schenkel steht, und
   der Restfehler der alten Bilanz mit L_GF skalierte.
   c:TEST_LINIENZUG_MODUS2 ist dafuer tabellengesteuert - ein weiterer Fall
   ist jetzt eine Zeile in *tlz-m2-faelle*.

2. RUECKNAHME des Schluss-Solves (vfl-zsolve-schluss-ziel, heute frueh
   eingebaut). Er loeste den letzten Fueller gegen Richtung UND Laenge und
   traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass er die
   letzte Gerade um 6.15 Grad verdrehte (hz-plan -90 -> -96.15), in der
   Zeichnung als schiefer Schenkel sichtbar. Das widerspricht der
   Entscheidung vom 2026-10-26: quer MUSS 0 sein, LAENGS DARF ABWEICHEN -
   der Hauptstrang bleibt gerade, der seitliche Versatz des ES-Elements ist
   dessen Bauform. Die Messwerte von heute (0.56 / 0.7 mm quer) stammen
   nicht von dieser Aenderung, sondern von der Laengenbilanz des gefalteten
   Laufs (35ebee1) - der Zweig blieb dort ungenutzt. Die Begruendung steht
   jetzt an der Aufrufstelle, damit niemand den Solve erneut baut.

3. laengs wird geprueft - als FORM-, nicht als Genauigkeitskriterium
   (erwartung_laengs_mm, Toleranz 5 mm). Der Wert ist die Ausladung des
   ES-Elements und je Fall eine Konstante (104.68 bei ES_Element_30,
   637.58 bei ES_Element_90). Punkt 2 war am Querwert NICHT erkennbar - die
   Verdrehung macht ihn gerade null, der Test meldete OK, gefunden wurde sie
   mit dem Auge. Ein verdrehter Hauptstrang zielt auf den Endpunkt und
   drueckt laengs auf ~0; daran faellt er auf. Gegengeprueft: mit kuenstlich
   auf 0.01 mm gesetzter Toleranz kippen alle fuenf Faelle auf ABWEICHUNG.

4. Alle sieben Ketten des Menueeintrags entstehen als Reihe auf Y=0, 20 m
   Abstand, statt verstreut. Die Modus-1-Skripte brauchen dafuer nur ihren
   EINEN point_abs (alles Weitere ist point_rel mit dL/hz); bei Modus 2
   mussten PT-Eintraege UND die Pfadkoordinaten in SEGS (Felder 6..9)
   mitwandern, sonst zeigt der Pfad woanders hin als Start und Ziel.
   Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind
   davon unabhaengig; Z blieb stehen, weil die Starthoehe ein Eingabewert
   des Solvers ist. Geprueft: erstes Segment beginnt exakt am Startpunkt,
   letztes endet exakt am Zielpunkt, Messwerte unveraendert.

5. Die drei letzten Verweise auf doc/VarioFoerderer_Linienzug_Prinzipien.md
   (bewusst unversioniert) tragen ihre Begruendung jetzt selbst: Entkopplung
   Neigung/XY, warum es genau EINEN Kletterer je Lauf gibt, und warum ein
   VF-Sub-Segment auf der 3-Grad-Basis beginnen und enden muss.

Geprueft: TEST_UNIT 897/897 (die 7 Tests der entfernten Funktion sind mit
ihr gegangen), TEST_LINIENZUG_MODUS2 5 von 5 OK, voller Menueablauf baut
sieben Ketten an den vorgesehenen Stellen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 14:28:57 +01:00
parent 11e334d0a2
commit b709f89404
12 changed files with 585 additions and 185 deletions
+55 -81
View File
@@ -11173,8 +11173,22 @@
;; aus einer Planungsphase vor der endgueltigen Menue-Zuordnung stammen. Seit
;; der Umbenennung tragen sie darum gar keine Modus-Nummer mehr, sondern ihre
;; ROLLE: sie rechnen die Hoehen (Z) durch, waehrend der Grundriss (XY) vom
;; gezeichneten Pfad kommt. Genau diese Entkopplung macht das Randwertproblem
;; loesbar (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md, Abschnitt 14.1).
;; gezeichneten Pfad kommt.
;;
;; Genau diese Entkopplung macht das Randwertproblem loesbar, und sie beruht
;; auf einer Eigenschaft der Bauteile: die Neigung eines Teils aendert seine
;; HOEHE, aber nicht seinen XY-FUSSABDRUCK. Ein Staustrecken-Teil mit
;; Planlaenge L belegt in der Draufsicht immer L - die 3D-Laenge waechst auf
;; L/cos(w), die Projektion bleibt L. Z-Ziel und Pfadtreue sind damit zwei
;; unabhaengige Probleme und duerfen nacheinander geloest werden:
;; XY = gezeichneter Pfad, reine KS-Kettung (wie Modus 3, mm-Drift akzeptiert)
;; Z = gerechnet, sodass das Kettenende die Ziel-Hoehe EXAKT trifft
;; Daher auch die zwei Phasen von vf-linienzug-modus2: erst alle Hoehen
;; durchrechnen, dann bauen.
;;
;; (Zum Gegensatz Modus 2 / Modus 3: Modus 3 baut vorwaerts, seine Endhoehe ist
;; ein ERGEBNIS - ein Anfangswertproblem. Modus 2 kennt Start UND Ziel je in
;; X/Y/Z und rechnet die Zwischenhoehen - ein Randwertproblem.)
;;
;; Gegenstueck: die vfl-pfad-*-Helfer weiter oben arbeiten auf dem
;; gezeichneten Pfad selbst (Eckwinkel pruefen, AS einfuegen, VF oeffnen/
@@ -11590,60 +11604,6 @@
(- (/ (- ep-na (* perp-es np-na)) dp-na) cc)
100.0))))
;; --- Schlussstueck: RICHTUNG und LAENGE gemeinsam aus der IST-Lage loesen ---
;; Nutzer-Vorgabe 2026-10-29: "nach der zweiten VF-Kurve den passenden Winkel
;; neu aus dem KS_AUS der Kurve und dem Zielpunkt rechnen".
;;
;; Warum das noetig ist: vfl-zsolve-es-fueller loest NUR die Laenge und
;; uebernimmt die Richtung unveraendert aus dem gezeichneten Pfad. Eine Laenge
;; verschiebt die Kette aber ausschliesslich ENTLANG ihrer Achse. Steht der
;; reale Kurvenausgang seitlich NEBEN der gezeichneten Geraden - und das tut er,
;; sobald die echten Eck-Bauteile nicht in die gezeichnete Ecke passen -, dann
;; laeuft die gebaute Achse PARALLEL zur Zielachse, und kein Fuellerwert der
;; Welt holt den Querversatz noch ein (realer Befund 2026-10-29: waagerechte
;; Kette, zwei 90-Grad-Vario-Kurven mit nur 269.9 mm gezeichnetem Zwischenstueck
;; -> 637.6 mm quer, 1424.4 mm laengs daneben).
;;
;; Gibt man die Richtung mit frei, stehen zwei Unbekannte (fill, hz) zwei
;; Gleichungen (X und Y des Zielpunkts) gegenueber - geschlossen loesbar, ohne
;; Iteration. Der Schwanz (Fueller + ab_3 + Motor + GF2 + Separator + ES) ist
;; starr; im Rahmen von hz hat sein Endpunkt die festen Komponenten
;; (fill + C) laengs und P quer.
;; Beide sind von hz UNABHAENGIG: vfl-zsolve-es-vektor dreht den ES-Vektor und
;; den Bezugsrahmen um denselben Winkel. Also ist D = Ziel - pt genau der um hz
;; gedrehte Vektor (fill + C, P), woraus folgt:
;; A = sqrt(|D|^2 - P^2) (Laengskomponente, Pythagoras)
;; fill = A - C
;; hz = Winkel(D) - atan2(P, A)
;; Damit wird der Zielpunkt in X UND Y exakt getroffen, nicht nur die ES-Achse.
;;
;; Das Schlussstueck weicht danach bewusst von der gezeichneten Richtung ab -
;; genau im Sinn des Leitsatzes bei vfl-eck-korrekturen: massgeblich ist die
;; reale Bauteilkette, der gezeichnete Pfad ist nur Hinweis.
;;
;; es-block = ES-Blockname oder nil (dann ohne ES-Element, P = 0).
;; Rueckgabe: (fill hz-grad) oder nil, wenn der Zielpunkt naeher liegt als der
;; Querversatz - dann gibt es keine Loesung und der Aufrufer faellt auf den
;; bisherigen Weg (Richtung aus dem Plan) zurueck.
(defun vfl-zsolve-schluss-ziel (pt endp seg-hz es-block gf2 rad3 /
vek cc pp p0 p1 dd aa)
(setq vek (if es-block (vfl-zsolve-es-vektor es-block seg-hz) nil))
(if vek
(setq cc (+ 196.0 (* (+ *vfk-feste-horizontal-kettenende* gf2) (cos rad3)) (car vek))
pp (cadr vek))
(setq cc (* (+ *vfk-stations-laenge* gf2) (cos rad3))
pp 0.0))
(setq p0 (list (car pt) (cadr pt))
p1 (list (car endp) (cadr endp)))
(setq dd (distance p0 p1))
(if (<= dd (+ (abs pp) 1.0))
nil
(progn
(setq aa (sqrt (- (* dd dd) (* pp pp))))
(list (- aa cc)
(- (/ (* 180.0 (angle p0 p1)) pi)
(/ (* 180.0 (atan pp aa)) pi))))))
(defun vf-linienzug-modus2 ( / ss k obj-liste startpunkt start-hoehe as-seite
endpunkt end-hoehe es-seite kette segmente segmente9 n i seg
seg-ent
@@ -11666,7 +11626,6 @@
longest-idx climbers nonclimber-len
nonclimber-cnt nkurve kurve-chords run-span
hor-koerper-len hor-pairs flat-p flat-zone-erste fill-len wahl3
schluss
rad3v feste-vf dH-adj dir-x dir-y fill-D end-hz
laengs-wert quer-wert soll-korrigiert
es-vek-fix es-along-fix as-along-fix m-ueb
@@ -12362,7 +12321,21 @@
;; ohnehin auf den Zielpunkt rechnet (vfl-zsolve-es-fueller).
;;
;; *vfl-min-climber-laenge* wird dadurch fuer die Auswahl nicht mehr
;; gebraucht (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md, Abschnitt 14).
;; gebraucht: es gibt keine Schwelle "ab welcher Laenge ist eine Gerade ein
;; Kletterer", sondern genau EINEN Kletterer je Lauf - die laengste.
;;
;; Grund ist das Modell dahinter: jede VF-Strecke im Pfad ist eine
;; Standard-VF-Einheit ohne eigenes AS/ES, also GF1 + Separator +
;; Umlenkstation + Vario-Koerper + Motorstation + GF2. Alle Teile liegen
;; kolinear auf derselben Pfad-Geraden; variieren ihre Laengen, verschieben
;; sich nur die inneren Grenzen, die Enden der Bruecke bleiben fix. Je
;; Bruecke steht damit ein 2-Gleichungs-System:
;; Summe der Planlaengen = gezeichnete Spannweite (aus dem Pfad)
;; Summe der Hoehenaenderung = delta-H zwischen den Ankern
;; Freie Variablen: Vario-Winkel (diskret) + GF1-Laenge + GF2-Laenge. Genau
;; das loest der vorhandene Solver (berechne-alle-winkel) - und er kennt
;; EINEN Vario-Koerper. Mehrere Kletterer passen deshalb nicht ins Modell,
;; unabhaengig von ihrer Laenge.
(setq longest-idx -1 i vf-start)
(while (<= i vf-ende)
(setq seg (nth i plan))
@@ -12817,28 +12790,29 @@
;; Separator + ES kuemmert sich der Back-Lauf selbst (siehe dort die
;; last-line-Reservierung).
(if (and (= i vf-ende) (= vf-ende (1- n)))
;; Letztes Segment UND Pfadende: RICHTUNG und LAENGE des Schlussstuecks
;; gemeinsam aus der IST-Lage loesen (vfl-zsolve-schluss-ziel), statt
;; die Richtung aus dem gezeichneten Pfad zu uebernehmen und nur die
;; Laenge zu loesen. Damit wird der Zielpunkt in X UND Y getroffen;
;; ein Querversatz, den die realen Eck-Bauteile vorher aufgebaut haben,
;; wird hier eingefangen statt bis ans Kettenende mitgeschleppt.
;; Scheitert der Solve (Ziel liegt naeher als der ES-Querversatz),
;; bleibt es beim bisherigen Weg: Richtung aus dem Plan, Laenge so, dass
;; der Endpunkt auf der ES-KS_AUS-Achse liegt (Spiegel der AS-Regel) -
;; bzw. ohne ES-Element direkt auf den Endpunkt.
(progn
(setq schluss (vfl-zsolve-schluss-ziel pt endpunkt seg-hz
(if es-vorhanden
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite))
br-gf2-exp rad3v))
(if schluss
(progn
(dbgmsg (strcat "SCHLUSS-SOLVE hz-plan=" (rtos seg-hz 2 3)
" hz-neu=" (rtos (cadr schluss) 2 3)
" fill=" (rtos (car schluss) 2 1)))
(setq fill-len (car schluss)
seg-hz (cadr schluss)))
;; letzter Fueller, MIT ES-Element: Laenge so, dass der ENDPUNKT auf
;; der ES-KS_AUS-ACHSE liegt (Spiegel der AS-Regel). Der Schwanz
;; (Fueller + ab_3 + Motor + GF2 + Separator + ES) verschiebt sich
;; starr entlang seg-hz mit dem Fueller; KS_AUS = pt + (fill + C)*dp +
;; perp-es*np, Achse u_a = seg-hz + ES-Turn. Aus (Endpunkt -
;; KS_AUS)*n_a = 0 folgt fill (n_a senkrecht zu u_a). OHNE ES-Element
;; (Nutzerwunsch): keine Achsen-Korrektur noetig, da nach Motor+GF2
;; nichts mehr gebaut wird - Fueller zielt direkt auf den Endpunkt.
;;
;; HIER WIRD NUR DIE LAENGE GELOEST, NIE DIE RICHTUNG. Am 2026-10-29
;; stand an dieser Stelle ein Solve, der beides freigab und damit den
;; Zielpunkt in X UND Y exakt traf (vfl-zsolve-schluss-ziel, wieder
;; entfernt). Rechnerisch war er korrekt - und trotzdem falsch: er
;; erreicht den Querausgleich, indem er die letzte Gerade dreht. Im
;; U-Form-Testfall waren das 6.15 Grad (hz-plan -90 -> -96.15), in der
;; Zeichnung sofort als schiefer Schenkel sichtbar.
;; Das widerspricht der Entscheidung vom 2026-10-26: quer zur
;; KS_AUS-Achse MUSS 0 sein, LAENGS DARF ABWEICHEN - der Hauptstrang
;; bleibt gerade, der seitliche Versatz des ES-Elements ist dessen
;; Bauform und kein Fehler. Beides zugleich geht nicht.
;; Wichtig fuer kuenftige Tests: eine solche Verdrehung ist am
;; Querwert NICHT erkennbar (sie macht ihn gerade null) - nur an der
;; Zeichnung bzw. am Vergleich von seg-hz mit dem Planwinkel.
(setq fill-len
(if es-vorhanden
(vfl-zsolve-es-fueller pt endpunkt seg-hz
@@ -12846,7 +12820,7 @@
br-gf2-exp rad3v)
(- (+ (* (- (car endpunkt) (car pt)) (cos (* seg-hz (/ pi 180.0))))
(* (- (cadr endpunkt) (cadr pt)) (sin (* seg-hz (/ pi 180.0)))))
(* (+ *vfk-stations-laenge* br-gf2-exp) (cos rad3v)))))))
(* (+ *vfk-stations-laenge* br-gf2-exp) (cos rad3v)))))
;; Gewoehnlicher Fueller: volle Planlaenge des Segments, abzueglich
;; der fest gebauten Teile, die auf GENAU diesem Segment stehen -
;; das AS am Laufanfang, Abschlussbogen + Motorstation am Laufende,
+13 -1
View File
@@ -609,7 +609,19 @@
;; EIN reines VF-Sub-Segment. Wichtig: es BEGINNT und ENDET auf der
;; 3-Grad-Basisneigung, weil Ein- und Ausgangsbogen denselben Winkel haben.
;; Dadurch lassen sich mehrere Sub-Segmente (und Vario-Kurven dazwischen)
;; beliebig aneinanderreihen (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md).
;; beliebig aneinanderreihen.
;;
;; Die Regel dahinter: der Vertikalbogen am ENDE eines VF (vor der
;; Motorstation) hat denselben Winkel wie der am ANFANG (nach der
;; Umlenkstation), und der abschliessende Bogen bringt die Strecke auf 3 Grad
;; NACH UNTEN - weil die Motorstation selbst mit 3 Grad geneigt eingebaut wird
;; und der Anschluss sonst knickt. Dasselbe gilt am anderen Ende: Umlenkstation
;; (VF-Start) und Separator+ES-Element (Kettenende) gibt es hardwareseitig nur
;; fuer die Anfahrt auf dieser Standard-Fallend-Basis; eine Anfahrt auf
;; STEIGENDER Basis ist physisch nicht vorgesehen.
;; Anfang und Ende auf derselben Basis zu halten ist also keine Konvention,
;; sondern die Voraussetzung dafuer, dass zwei Sub-Segmente ueberhaupt
;; aneinanderpassen.
;; best-winkel=0 => horizontales Sub-Segment (Boegen fest auf_3/ab_3).
(defun vfs-vf-koerper (aktueller-punkt richtung best-winkel L_VF hz /
bogen-name bogen-mass bogen-dx bogen-dz z-ein)
+94 -6
View File
@@ -87,7 +87,44 @@ dem gewuenschten Modus:
Lauf ohne manuellen Zusatzschritt, aber ohne gleichzeitige visuelle Kontrolle
aller Zeichnungen am Ende. Sinnvoll fuer reine CI-artige Validierung.
## Referenzfaelle Linienzug Modus 2 (manuell, mit Soll-Werten)
## Anordnung der Linienzug-Testketten
Der Menueeintrag **Tests -> Foerderer-Linienzug** faehrt drei Befehle
nacheinander (`TEST_LINIENZUG`, `TEST_LINIENZUG_STUFE2`,
`TEST_LINIENZUG_MODUS2`) und baut dabei **sieben** Ketten. Damit sie
nebeneinander auf einer Grundlinie entstehen statt verstreut, tragen die
Testdaten versetzte Startpunkte - 20 m Abstand, alle auf `Y = 0`:
| X | Z | Kette | Datei |
|---|---|---|---|
| 0 | 2154 | Modus 1, Standardfall | `linienzug_tests.json` |
| 20000 | 2154 | Modus 1, Stufe-2-Fallback | `linienzug_tests_stufe2.json` |
| 40000 | 0 | Variante A (Vario-Kurve) | `linienzug_modus2_variokurve.json` |
| 60000 | 0 | Variante B (GF-Bogen) | `linienzug_modus2_gfbogen.json` |
| 80000 | 355 | U-Form 1 (GF alles am Einlauf) | `..._uform_gf1.json` |
| 100000 | 711 | U-Form 2 (1/2 + 1/2) | `..._uform_halb.json` |
| 120000 | 709 | U-Form 3 (steilerer Winkel) | `..._uform_halb_steil.json` |
Die Koordinaten sind also **nicht** die der aufgezeichneten Laeufe, die
uebrige Geometrie schon. Verschoben wurde rein translatorisch: Laengen,
Winkel und die geprueften Abweichungen sind davon unabhaengig. `Z` blieb
jeweils stehen - die Starthoehe ist ein Eingabewert des Solvers, kein
Layout-Parameter.
Technisch unterscheiden sich die beiden Datenarten: die Modus-1-Skripte
brauchen nur ihren EINEN `point_abs` (alles Weitere ist `point_rel` mit
`dL`/`hz`), waehrend bei Modus 2 sowohl die `PT`-Eintraege ALS AUCH die
Pfadkoordinaten in `SEGS` (Felder 6..9) mitwandern muessen - sonst zeigt der
Pfad woanders hin als Start und Ziel.
## Referenzfaelle Linienzug Modus 2 (`c:TEST_LINIENZUG_MODUS2`)
Fuenf aufgezeichnete Laeufe, die als zwei Paare gebildet sind: A/B
unterscheiden die Eck-BAUTEILART, U-Form 1..3 den gefalteten Lauf nach
GF-Verteilung und Winkel. Ausgefuehrt ueber Menue -> Tests ->
Foerderer-Linienzug.
### Erster und zweiter Fall: Eck-Bauteilart
Zwei Laeufe auf **demselben gezeichneten Pfad**, die sich nur in der
Segment-Klassifizierung unterscheiden. Sie decken die beiden Eck-Bauteilarten
@@ -132,20 +169,71 @@ letzte Gerade auf der gezeichneten Linie und der ES-`KS_AUS` landet seitlich
daneben, oder umgekehrt. Entschieden ist: der Hauptstrang bleibt gerade, der
seitliche Versatz des ES-Elements ist dessen Bauform und kein Fehler.
**`laengs` wird trotzdem geprueft** - nicht als Genauigkeits-, sondern als
FORMkriterium (`erwartung_laengs_mm` in den Testdaten, Toleranz 5 mm). Der Wert
ist die Ausladung des ES-Elements und damit je Fall eine Konstante: 104.68 mm
bei `ES_Element_30`, 637.58 mm bei `ES_Element_90`.
Grund: am 2026-10-29 loeste ein Experiment den Schluss-Fueller gegen Richtung
UND Laenge und traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass
es die letzte Gerade um 6.15 Grad verdrehte. `quer` und `dZ` waren dabei NULL,
der Test meldete brav OK, und der schiefe Schenkel fiel nur beim Blick in die
Zeichnung auf. Ein verdrehter Hauptstrang zielt auf den Endpunkt und drueckt
`laengs` von ~638 mm auf ~0 - genau daran ist er zu erkennen.
Die Pruefung selbst ist gegengeprueft: mit einer kuenstlich auf 0.01 mm
gesetzten Toleranz kippen alle fuenf Faelle auf ABWEICHUNG.
Im Protokoll muessen die Zuschlags-Zeilen erscheinen: `AS-Fussabdruck`,
`Eck-Korrektur` je Ecke, und bei Variante A zusaetzlich
`Abschluss-Fussabdruck`. **Eine FEHLENDE Zeile ist das Warnsignal** - sie
bedeutet, dass ein Eck-Bauteil nicht messbar war und die Ecke unkorrigiert
blieb (so wurde der 2.4-mm-Rest bei Variante B gefunden).
> Noch nicht automatisiert. Dafuer muesste der Testfall den Pfad selbst per
> `entmake` zeichnen und das Eingabe-Journal replayen; das Journal einer
> gebauten Kette laesst sich mit `lib/vf_journal_export.py` aus der Zeichnung
> ziehen. Die reinen Rechenkerne dieser Faelle sind dagegen bereits file-frei
> abgedeckt (`tu-tests-vfl-parallel` in `test_unit.lsp`: `vfl-eck-zerlegen`,
> **Automatisiert seit 2026-10-27** als `c:TEST_LINIENZUG_MODUS2` (Menue:
> Tests -> Foerderer-Linienzug). Der Pfad muss dafuer NICHT gezeichnet werden:
> ein Modus-2-Journal traegt einen `SEGS`-Eintrag mit der kompletten
> Segment-Essenz und ist damit von den Original-Objekten unabhaengig - der
> Test spielt schlicht das mit `lib/vf_journal_export.py` ausgelesene Journal
> ab. Die reinen Rechenkerne sind zusaetzlich file-frei abgedeckt
> (`tu-tests-vfl-parallel` in `test_unit.lsp`: `vfl-eck-zerlegen`,
> `vfl-es-achs-reserve`, `vfl-projiziere-neigung` - jeweils mit den echten
> Messwerten aus diesen beiden Laeufen).
### Dritter bis fuenfter Fall: gefalteter Lauf (U-Form)
Aufgezeichnet 2026-10-29, Datendateien `tests/testdata/linienzug_modus2_uform_*.json`.
Der Pfad wechselt ueber zwei 90-Grad-Vario-Kurven **dreimal die
Fahrtrichtung**; die Kletterstrecke liegt dadurch in einem ANDEREN Schenkel als
der Lauf-Eingang. Genau diese Konstellation war bis 2026-10-29 falsch
bilanziert (gemessen 1424 mm quer), weil Posten dem falschen Schenkel
zugerechnet wurden.
| Segment | Art | Mass |
|---|---|---|
| 1 | Linie | L = 5855 mm, hz = 90 |
| 2 | Bogen | 90 Grad rechts, R500 -> **Vario-Kurve aussen** |
| 3 | Linie | L = 270 mm, hz = 0 (automatisch VF) |
| 4 | Bogen | 90 Grad rechts, R500 -> **Vario-Kurve aussen** |
| 5 | Linie | L = 7806 mm, hz = -90 (der Kletterer) |
| Fall | GF-Verteilung | Winkel-Option | Testdatei |
|---|---|---|---|
| U-Form 1 | alles am Einlauf (GF1) | 2 | `..._uform_gf1.json` |
| U-Form 2 | 1/2 GF1 + 1/2 GF2 | 2 (= 9 Grad) | `..._uform_halb.json` |
| U-Form 3 | 1/2 GF1 + 1/2 GF2 | 3 (steiler) | `..._uform_halb_steil.json` |
**Warum drei und nicht einer:** die GF-VERTEILUNG entscheidet, ob ueberhaupt
Gefaellestrecke im fremden Schenkel steht (und damit, ob Nachrechner und das
unterdrueckte Fueller-A greifen) - mit "alles am Einlauf" liegt das gesamte GF1
dort, mit 1/2+1/2 nur die Haelfte. Der WINKEL ist noetig, weil der Restfehler
der alten Bilanz mit `L_GF` skalierte: bei 6 Grad waren es 90 mm, bei 9 Grad
934 mm. Zwei Laeufe mit demselben Winkel haetten den Fehler also beinahe
verdeckt.
Soll-Ergebnis wie oben: `quer` und `dZ` jeweils ~0 (gemessen 0.56 mm bei
9 Grad und 0.7 mm bei der steileren Option), `laengs` ~638 mm - das ist die
Ausladung des `ES_Element_90_links` und in allen drei Faellen gleich.
## alltests.json — Testregistry
Die Datei `tests/alltests.json` ist die zentrale Registry aller Test-Module.
+103 -25
View File
@@ -270,7 +270,7 @@
;; ============================================================
;; MODUS 2 (aus 3D-Linie mit Zielhoehe) - Replay zweier echter Laeufe
;; MODUS 2 (aus 3D-Linie mit Zielhoehe) - Replay echter Laeufe
;; ============================================================
;; Anders als die Modus-1-Faelle oben braucht Modus 2 KEINE Mocks und KEINEN
;; gezeichneten Pfad: sein Journal traegt einen SEGS-Eintrag mit der kompletten
@@ -279,19 +279,51 @@
;; schon vfl-konvertiere-ent beruht (vfl-journal-hat-segs-p). Der Test spielt
;; daher das echte, aus der Zeichnung ausgelesene Journal ab.
;;
;; Die beiden Faelle sind BEWUSST ein Paar: derselbe Pfad, nur die 90-Grad-Ecke
;; einmal als Vario-Kurve (waagerecht) und einmal als GF-Bogen (geneigt). Sie
;; laufen durch verschiedene Zweige - mit und ohne flache Zone - und genau der
;; VERGLEICH hat am 2026-10-26/27 Fehler aufgedeckt, die ein einzelner Lauf
;; nicht gezeigt haette (ES-Fussabdruck am falschen Segment: 878 mm nur in der
;; GF-Bogen-Variante). Einen davon zu loeschen nimmt dem Test seinen Wert.
;; Die Faelle sind zwei BEWUSST gebildete Paare, kein Sammelsurium:
;;
;; Aufgezeichnet mit lib/vf_journal_export.py aus einem echten BricsCAD-Lauf.
;; A/B (Ecke als Vario-Kurve bzw. als GF-Bogen) - derselbe Pfad, nur die
;; 90-Grad-Ecke einmal waagerecht und einmal geneigt eingebaut. Sie laufen
;; durch verschiedene Zweige (mit und ohne flache Zone), und genau der
;; VERGLEICH hat am 2026-10-26/27 Fehler aufgedeckt, die ein einzelner
;; Lauf nicht gezeigt haette (ES-Fussabdruck am falschen Segment: 878 mm
;; nur in der GF-Bogen-Variante).
;;
;; U-Form 1..3 (gefalteter Lauf) - der Pfad wechselt ueber zwei 90-Grad-
;; Vario-Kurven dreimal die Fahrtrichtung, die Kletterstrecke liegt
;; dadurch in einem ANDEREN Schenkel als der Lauf-Eingang. Hier variieren
;; GF-VERTEILUNG (alles am Einlauf vs. 1/2+1/2) und WINKEL. Beides ist
;; noetig: die Verteilung entscheidet, ob ueberhaupt GF im fremden
;; Schenkel steht (Nachrechner, Fueller-A), und der Restfehler der alten
;; Bilanz skalierte mit L_GF, also mit dem Winkel (6 Grad 90 mm, 9 Grad
;; 934 mm) - zwei Laeufe mit demselben Winkel haetten das verdeckt.
;;
;; Einen Fall zu loeschen nimmt dem Test den jeweiligen Vergleich und damit
;; seinen Wert.
;;
;; Aufgezeichnet mit lib/vf_journal_export.py aus echten BricsCAD-Laeufen
;; (A/B am 2026-10-27, U-Form am 2026-10-29).
;; Pruefkriterium (Nutzer-Vorgabe 2026-10-26): quer zur ES-KS_AUS-Achse und dZ
;; MUESSEN ~0 sein, laengs DARF abweichen (Ausladung des ES-Elements).
(setq *tlz-m2-toleranz* 1.0) ; mm; 0.2 ist die Messaufloesung der Blockmasse
;; Toleranz fuer den LAENGS-Wert gegen "erwartung_laengs_mm" aus den Testdaten.
;; Der Wert ist die Ausladung des ES-Elements und damit je Fall eine Konstante
;; (gemessen: 104.68 mm bei ES_Element_30, 637.58 mm bei ES_Element_90) - 5 mm
;; reichen also fuer Rundung, ohne echte Abweichungen durchzulassen.
;;
;; Warum ueberhaupt geprueft, wo laengs doch ausdruecklich abweichen DARF:
;; Am 2026-10-29 loeste ein Experiment den Schluss-Fueller gegen Richtung UND
;; Laenge und traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass
;; es die letzte Gerade um 6.15 Grad verdrehte (sichtbar schiefer Schenkel im
;; U-Form-Fall). quer und dZ waren dabei NULL, der Test meldete OK; gefunden
;; wurde der Fehler nur mit dem Auge in der Zeichnung.
;; laengs ist der Wert, der das verraet: ein verdrehter Hauptstrang zielt auf
;; den Endpunkt und drueckt laengs von ~638 mm auf ~0. Die Pruefung ist also
;; kein zweites Genauigkeitskriterium, sondern ein Formkriterium - sie stellt
;; sicher, dass der ES-Versatz noch da ist, wo er hingehoert.
(setq *tlz-m2-laengs-toleranz* 5.0)
;; Wert als String - eigene Kopie statt hmrec:als-string aus
;; test_hm_recformat.lsp: diese Datei soll fuer sich allein ladbar bleiben.
(defun tlz-m2-str (v)
@@ -321,7 +353,8 @@
;; Einen Modus-2-Fall abspielen. Rueckgabe: (status laengs quer dz offen).
(defun tlz-m2-run (json-datei test-id anzeige /
daten journal meta offen err status abw j
old-headless old-gui quer dz laengs)
old-headless old-gui quer dz laengs
soll-laengs laengs-ok)
(if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek))
(princ (strcat "\n\n--- " anzeige " ---"))
;; Vorbelegen, damit der Ergebnis-Record auch im Fehlerzweig Zahlen hat -
@@ -375,38 +408,83 @@
(if (> offen 0)
(princ (strcat "\n WARNUNG: " (itoa offen)
" Journal-Eintraege NICHT verbraucht (Ablauf weicht ab).")))
;; laengs gegen den erwarteten ES-Versatz pruefen, sofern die
;; Testdaten einen nennen (siehe *tlz-m2-laengs-toleranz*).
(setq soll-laengs (if meta (ssg-val meta "erwartung_laengs_mm") nil))
(setq laengs-ok
(if (numberp soll-laengs)
(<= (abs (- laengs (float soll-laengs))) *tlz-m2-laengs-toleranz*)
T))
(if (not laengs-ok)
(princ (strcat "\n WARNUNG: laengs " (rtos laengs 2 1)
" statt erwarteter " (rtos (float soll-laengs) 2 1)
" mm - der Hauptstrang zeigt nicht mehr in die"
" gezeichnete Richtung (ES-Versatz verschwunden?).")))
(setq status
(if (and (<= (abs quer) *tlz-m2-toleranz*)
(<= (abs dz) *tlz-m2-toleranz*)
laengs-ok
(= offen 0))
"OK" "ABWEICHUNG"))
(princ (strcat "\n -> " status
" (Soll: |quer| und |dZ| <= " (rtos *tlz-m2-toleranz* 2 1)
" mm, laengs frei)"))))
" mm, laengs = "
(if (numberp soll-laengs)
(strcat (rtos (float soll-laengs) 2 0) " +/- "
(rtos *tlz-m2-laengs-toleranz* 2 0) " mm")
"frei")
")"))))
(ssg-end)))
(list status laengs quer dz offen))
(defun c:TEST_LINIENZUG_MODUS2 ( / basis a b)
;; Testfall-Tabelle: (Dateiname test-id Anzeigename). Ein weiterer Fall ist
;; damit EINE Zeile - der Ablauf darunter ist generisch. Reihenfolge =
;; Ausgabereihenfolge; die beiden Paare stehen bewusst beieinander.
(setq *tlz-m2-faelle*
(list
(list "linienzug_modus2_variokurve.json" "LZ_M2_variokurve"
"Variante A: Ecke = Vario-Kurve")
(list "linienzug_modus2_gfbogen.json" "LZ_M2_gfbogen"
"Variante B: Ecke = GF-Bogen")
(list "linienzug_modus2_uform_gf1.json" "LZ_M2_uform_gf1"
"U-Form 1: GF alles am Einlauf")
(list "linienzug_modus2_uform_halb.json" "LZ_M2_uform_halb"
"U-Form 2: GF 1/2 + 1/2")
(list "linienzug_modus2_uform_halb_steil.json" "LZ_M2_uform_halb_steil"
"U-Form 3: GF 1/2 + 1/2, steilere Winkel-Option")))
(defun c:TEST_LINIENZUG_MODUS2 ( / basis fall r erg zeilen anzahl-ok)
;; Doppelte Backslashes: "\t" waere in AutoLISP ein TABULATOR, der Pfad
;; wuerde zu "...dxfmakros<TAB>ests<TAB>estdata" (real passiert 2026-10-27).
(setq basis (strcat (getenv "DXFMAKRO") "\\tests\\testdata\\"))
(princ "\n================================================================")
(princ "\n TEST_LINIENZUG_MODUS2 - zwei Varianten DERSELBEN Strecke")
(princ (strcat "\n TEST_LINIENZUG_MODUS2 - " (itoa (length *tlz-m2-faelle*))
" Ketten aus echten BricsCAD-Laeufen"))
(princ "\n================================================================")
(setq a (tlz-m2-run (strcat basis "linienzug_modus2_variokurve.json")
"LZ_M2_variokurve" "Variante A: Ecke = Vario-Kurve"))
(setq b (tlz-m2-run (strcat basis "linienzug_modus2_gfbogen.json")
"LZ_M2_gfbogen" "Variante B: Ecke = GF-Bogen"))
(setq erg '() zeilen '() anzahl-ok 0)
(foreach fall *tlz-m2-faelle*
(setq r (tlz-m2-run (strcat basis (car fall)) (cadr fall) (caddr fall)))
(if (= (car r) "OK") (setq anzahl-ok (1+ anzahl-ok)))
(setq erg (cons (list (caddr fall) (car r)) erg))
(setq zeilen
(cons (strcat " { \"test_id\": \"" (cadr fall)
"\", \"status\": \"" (car r)
"\", \"quer_mm\": " (rtos (caddr r) 2 2)
", \"dz_mm\": " (rtos (cadddr r) 2 2)
", \"laengs_mm\": " (rtos (cadr r) 2 2) " }")
zeilen)))
(setq erg (reverse erg) zeilen (reverse zeilen))
(princ "\n\n================================================================")
(princ (strcat "\n ERGEBNIS: Variante A " (car a) " | Variante B " (car b)))
(princ "\n ERGEBNIS")
(princ "\n----------------------------------------------------------------")
(foreach e erg
(princ (strcat "\n " (car e) ": " (cadr e))))
(princ (strcat "\n----------------------------------------------------------------"
"\n " (itoa anzahl-ok) " von " (itoa (length *tlz-m2-faelle*))
" OK"))
(princ "\n================================================================")
;; Ergebnis fuer run-all (Konvention wie linienzug:export-results)
(setq *linienzug-m2-test-results*
(strcat " { \"test_id\": \"LZ_M2_variokurve\", \"status\": \"" (car a)
"\", \"quer_mm\": " (rtos (caddr a) 2 2)
", \"dz_mm\": " (rtos (cadddr a) 2 2) " },\n"
" { \"test_id\": \"LZ_M2_gfbogen\", \"status\": \"" (car b)
"\", \"quer_mm\": " (rtos (caddr b) 2 2)
", \"dz_mm\": " (rtos (cadddr b) 2 2) " }"))
;; Ergebnis fuer run-all (Konvention wie linienzug:export-results).
;; ssg-join aus ssg_core - die Zeilen sind bereits fertige JSON-Objekte.
(setq *linienzug-m2-test-results* (ssg-join zeilen ",\n"))
(princ)
)
-49
View File
@@ -3036,54 +3036,6 @@
)
;; --- Schlussstueck: Richtung UND Laenge aus der IST-Lage ---------------------
;; vfl-zsolve-schluss-ziel loest den letzten Fueller gegen den Zielpunkt, mit der
;; Richtung als zweiter Unbekannter. Mit es-block = nil braucht die Funktion
;; weder Zeichnung noch Blockdatei - der Querversatz P ist dann 0 und uebrig
;; bleibt die reine Geometrie.
;; Bewusst NICHT gegen eine nachgerechnete Konstante C geprueft (das waere die
;; Formel ein zweites Mal hingeschrieben), sondern gegen Eigenschaften, die
;; unabhaengig von C gelten: der Winkel zeigt exakt zum Ziel, und eine
;; Zielverschiebung bzw. ein groesseres GF2 schlaegt 1:1 auf die Laenge durch.
(defun tu-tests-vfl-schluss ( / _rad3 _p0 _a _b _c _d)
(princ "\n[vf_linienzug Schlussstueck]")
(setq _rad3 (/ (* 3.0 pi) 180.0)
_p0 '(0.0 0.0 0.0))
;; Der Winkel zeigt ohne ES-Element exakt zum Zielpunkt (P = 0).
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-ost"
0.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-nord"
90.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
;; 3/4/5-Dreieck: die Richtung folgt dem Ziel, NICHT dem uebergebenen seg-hz.
;; Genau das ist der Kern der Aenderung - darum wird hier ein voellig anderer
;; Planwinkel (-137) hineingegeben.
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-folgt-ziel-nicht-plan"
(/ (* 180.0 (atan 4000.0 3000.0)) pi)
(cadr (vfl-zsolve-schluss-ziel _p0 '(3000.0 4000.0 0.0) -137.0 nil 0.0 _rad3)))
;; Laenge: 1000 mm weiter entferntes Ziel -> 1000 mm mehr Fueller.
(setq _a (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3))
_b (car (vfl-zsolve-schluss-ziel _p0 '(11000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-folgt-ziel" 1000.0 (- _b _a))
;; GF2 steht im Schwanz und liegt unter 3 Grad: 1000 mm GF2 verbrauchen
;; 1000*cos(3) in der Laengsrichtung, der Fueller wird genau darum kuerzer.
(setq _c (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 1000.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/gf2-verkuerzt-fueller"
(* 1000.0 (cos _rad3)) (- _a _c))
;; Die Loesung ist richtungsunabhaengig: dasselbe Ziel, um 90 Grad gedreht,
;; ergibt dieselbe Fuellerlaenge.
(setq _d (car (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-drehinvariant" _a _d)
;; Kein loesbarer Fall: Ziel liegt auf dem Startpunkt -> nil (Aufrufer faellt
;; dann auf den bisherigen Weg zurueck, statt etwas zu raten).
(tu-nil "vfl-zsolve-schluss-ziel/ziel-auf-startpunkt"
(vfl-zsolve-schluss-ziel _p0 '(0.0 0.0 0.0) 0.0 nil 0.0 _rad3))
)
(defun c:TEST_UNIT ( / out-dir report)
(tu-reset)
@@ -3097,7 +3049,6 @@
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
"tu-tests-vfl-schluss"
"tu-tests-werkzeuge" "tu-tests-kf" "tu-tests-hoehen-fam")
(tu-run-block fn))
+6 -6
View File
@@ -1,6 +1,6 @@
[
{
"beschreibung": "Linienzug Modus 2, Variante B: 90-Grad-Ecke als GF-BOGEN (geneigt eingebaut). Deckt die Neigungs-Projektion der Eck-Korrektur ab (vfl-projiziere-neigung) und den Zweig OHNE flache Zone, in dem der ES-Fussabdruck frueher faelschlich vom VF-Lauf abgezogen wurde (878 mm). Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf.",
"beschreibung": "Linienzug Modus 2, Variante B: 90-Grad-Ecke als GF-BOGEN (geneigt eingebaut). Deckt die Neigungs-Projektion der Eck-Korrektur ab (vfl-projiziere-neigung) und den Zweig OHNE flache Zone, in dem der ES-Fussabdruck frueher faelschlich vom VF-Lauf abgezogen wurde (878 mm). Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
"test_id": "LZ_M2_gfbogen",
"kurz": "Ecke als GF-Bogen",
"erwartung_quer_mm": 0,
@@ -10,8 +10,8 @@
},
{
"art": "PT",
"x": 6373.07914,
"y": 6047.735576,
"x": 60000.0,
"y": 0.0,
"z": 0.0
},
{
@@ -32,8 +32,8 @@
},
{
"art": "PT",
"x": 17373.07914,
"y": -267.387621,
"x": 71000.0,
"y": -6315.123197,
"z": 184.3
},
{
@@ -54,7 +54,7 @@
},
{
"art": "SEGS",
"wert": "Linie|0|9700|0|links|6373.07914|6047.735576|16073.07914|6047.735576;Bogen|0|707.106781|90|rechts|16073.07914|6047.735576|16573.07914|5547.735576;Linie|-90|4295.507955|0|links|16573.07914|5547.735576|16573.07914|1252.227621;Bogen|-90|258.819045|30|links|16573.07914|1252.227621|16640.066438|1002.227621;Linie|-60|1466.025404|0|links|16640.066438|1002.227621|17373.07914|-267.387621"
"wert": "Linie|0|9700|0|links|60000|0|69700|0;Bogen|0|707.106781|90|rechts|69700|0|70200|-500;Linie|-90|4295.507955|0|links|70200|-500|70200|-4795.507955;Bogen|-90|258.819045|30|links|70200|-4795.507955|70266.987298|-5045.507955;Linie|-60|1466.025404|0|links|70266.987298|-5045.507955|71000|-6315.123197"
},
{
"art": "STR",
+99
View File
@@ -0,0 +1,99 @@
[
{
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form): der Pfad wechselt ueber zwei 90-Grad-Vario-Kurven dreimal die Fahrtrichtung, die Kletterstrecke liegt dadurch in einem ANDEREN Schenkel als der Lauf-Eingang. GF-Verteilung 1 (alles am Einlauf, GF1) - diese Verteilung war bis 2026-10-29 durch keinen Test abgedeckt. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
"test_id": "LZ_M2_uform_gf1",
"kurz": "U-Form, GF alles am Einlauf",
"erwartung_quer_mm": 0,
"erwartung_dz_mm": 0,
"erwartung_laengs_mm": 638,
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
},
{
"art": "PT",
"x": 80000.0,
"y": 0.0,
"z": 355.289671
},
{
"art": "REAL",
"wert": 355.3
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "PT",
"x": 81269.916932,
"y": 0.0,
"z": 355.289671
},
{
"art": "REAL",
"wert": 355.3
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "SEGS",
"wert": "Linie|90|5854.769733|0|links|80000|0|80000|5854.769733;Bogen|90|707.106781|90|rechts|80000|5854.769733|80500|6354.769733;Linie|0|269.916931|0|links|80500|6354.769733|80769.916932|6354.769733;Bogen|0|707.106781|90|rechts|80769.916932|6354.769733|81269.916932|5854.769733;Linie|-90|5854.769733|0|links|81269.916932|5854.769733|81269.916932|0"
},
{
"art": "STR",
"wert": "m2v2"
},
{
"art": "STR",
"wert": "vf"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "mit-gf1"
},
{
"art": "STR",
"wert": "3"
},
{
"art": "INT",
"wert": 2
},
{
"art": "STR",
"wert": "1"
}
]
+99
View File
@@ -0,0 +1,99 @@
[
{
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form), GF-Verteilung 2 (1/2 GF1 + 1/2 GF2). DAS ist der Lauf, an dem die Laengenbilanz des gefalteten Laufs entwickelt und gemessen wurde: 1424 -> 934 -> 402 -> 0.56 mm quer (9 Grad). Er deckt alle vier Teilstuecke zugleich ab - Eingangs-Hardware im fremden Schenkel, kletter-ende-fp, GF1-Fremdanteil (Nachrechner) und das unterdrueckte Fueller-A. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
"test_id": "LZ_M2_uform_halb",
"kurz": "U-Form, GF 1/2+1/2",
"erwartung_quer_mm": 0,
"erwartung_dz_mm": 0,
"erwartung_laengs_mm": 638,
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
},
{
"art": "PT",
"x": 100000.0,
"y": 0.0,
"z": 710.579341
},
{
"art": "REAL",
"wert": 710.6
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "PT",
"x": 101269.916932,
"y": -1951.333591,
"z": 710.579341
},
{
"art": "REAL",
"wert": 710.6
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "SEGS",
"wert": "Linie|90|5854.769733|0|links|100000|0|100000|5854.769733;Bogen|90|707.106781|90|rechts|100000|5854.769733|100500|6354.769733;Linie|0|269.916931|0|links|100500|6354.769733|100769.916932|6354.769733;Bogen|0|707.106781|90|rechts|100769.916932|6354.769733|101269.916932|5854.769733;Linie|-90|7806.103325|0|links|101269.916932|5854.769733|101269.916932|-1951.333591"
},
{
"art": "STR",
"wert": "m2v2"
},
{
"art": "STR",
"wert": "vf"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "mit-gf1"
},
{
"art": "STR",
"wert": "3"
},
{
"art": "INT",
"wert": 2
},
{
"art": "STR",
"wert": "2"
}
]
+99
View File
@@ -0,0 +1,99 @@
[
{
"beschreibung": "Linienzug Modus 2, GEFALTETER Lauf (U-Form) wie LZ_M2_uform_halb, aber mit der naechststeileren Winkel-Option. Der Restfehler der alten Bilanz skalierte mit L_GF und damit mit dem Winkel (6 Grad: 90 mm, 9 Grad: 934 mm) - zwei Winkel auf derselben Pfadfamilie sichern deshalb mehr ab als zwei Laeufe mit demselben. Aufgezeichnet 2026-10-29 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
"test_id": "LZ_M2_uform_halb_steil",
"kurz": "U-Form, GF 1/2+1/2, steilere Winkel-Option",
"erwartung_quer_mm": 0,
"erwartung_dz_mm": 0,
"erwartung_laengs_mm": 638,
"erwartung_hinweis": "quer zur ES-KS_AUS-Achse MUSS ~0 sein und dZ ~0; laengs darf abweichen - das ist die Ausladung des ES-Elements und kein Fehler. Der laengs-Wert von rund 638 mm ist die Ausladung des ES_Element_90_links und in allen drei U-Form-Faellen gleich; geprueft werden nur quer und dZ."
},
{
"art": "PT",
"x": 120000.0,
"y": 0.0,
"z": 709.285191
},
{
"art": "REAL",
"wert": 709.3
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "PT",
"x": 121269.916932,
"y": 0.077406,
"z": 709.275779
},
{
"art": "REAL",
"wert": 709.3
},
{
"art": "STR",
"wert": "1"
},
{
"art": "STR",
"wert": "90"
},
{
"art": "STR",
"wert": "1"
},
{
"art": "SEGS",
"wert": "Linie|90|5854.769733|0|links|120000|-21.403816|120000|5833.365917;Bogen|90|707.106781|90|rechts|120000|5833.365917|120500|6333.365917;Linie|0|269.916931|0|links|120500|6333.365917|120769.916932|6333.365917;Bogen|0|707.106781|90|rechts|120769.916932|6333.365917|121269.916932|5833.365917;Linie|-90|5854.769733|0|links|121269.916932|5833.365917|121269.916932|-21.403816"
},
{
"art": "STR",
"wert": "m2v2"
},
{
"art": "STR",
"wert": "vf"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "vario-kurve"
},
{
"art": "STR",
"wert": "aussen"
},
{
"art": "STR",
"wert": "mit-gf1"
},
{
"art": "STR",
"wert": "3"
},
{
"art": "INT",
"wert": 3
},
{
"art": "STR",
"wert": "2"
}
]
+6 -6
View File
@@ -1,6 +1,6 @@
[
{
"beschreibung": "Linienzug Modus 2, Variante A: 90-Grad-Ecke als VARIO-KURVE (waagerecht eingebaut), Segment 3 dadurch automatisch VF. Deckt die flache Zone ab (Abschluss-Fussabdruck Bogen+Motorstation) und die Eck-Korrektur von 93.8 mm je Nachbargerade. Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf.",
"beschreibung": "Linienzug Modus 2, Variante A: 90-Grad-Ecke als VARIO-KURVE (waagerecht eingebaut), Segment 3 dadurch automatisch VF. Deckt die flache Zone ab (Abschluss-Fussabdruck Bogen+Motorstation) und die Eck-Korrektur von 93.8 mm je Nachbargerade. Aufgezeichnet 2026-10-27 aus einem echten BricsCAD-Lauf. Startpunkt fuer die Testreihe versetzt: alle Koordinaten (Start-/Zielpunkt und Pfadsegmente) um einen gemeinsamen Vektor verschoben, damit TEST_LINIENZUG_MODUS2 die Ketten nebeneinander auf einer Grundlinie baut statt verstreut. Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind davon unabhaengig; Z bleibt unveraendert, weil die Starthoehe ein Eingabewert des Solvers ist.",
"test_id": "LZ_M2_variokurve",
"kurz": "Ecke als Vario-Kurve",
"erwartung_quer_mm": 0,
@@ -10,8 +10,8 @@
},
{
"art": "PT",
"x": 20702.423223,
"y": 6047.735576,
"x": 40000.0,
"y": 0.0,
"z": 0.0
},
{
@@ -32,8 +32,8 @@
},
{
"art": "PT",
"x": 31702.423223,
"y": -267.387621,
"x": 51000.0,
"y": -6315.123197,
"z": 184.3
},
{
@@ -54,7 +54,7 @@
},
{
"art": "SEGS",
"wert": "Linie|0|9700|0|links|20702.423223|6047.735576|30402.423223|6047.735576;Bogen|0|707.106781|90|rechts|30402.423223|6047.735576|30902.423223|5547.735576;Linie|-90|4295.507955|0|links|30902.423223|5547.735576|30902.423223|1252.227621;Bogen|-90|258.819045|30|links|30902.423223|1252.227621|30969.410521|1002.227621;Linie|-60|1466.025404|0|links|30969.410521|1002.227621|31702.423223|-267.387621"
"wert": "Linie|0|9700|0|links|40000|0|49700|0;Bogen|0|707.106781|90|rechts|49700|0|50200|-500;Linie|-90|4295.507955|0|links|50200|-500|50200|-4795.507955;Bogen|-90|258.819045|30|links|50200|-4795.507955|50266.987298|-5045.507955;Linie|-60|1466.025404|0|links|50266.987298|-5045.507955|51000|-6315.123197"
},
{
"art": "STR",
+2 -2
View File
@@ -8,8 +8,8 @@
},
{
"typ": "point_abs",
"wert": [-1289.407125, 95.871332, 2154],
"kommentar": "getpoint Startpunkt der Kette"
"wert": [0.0, 0.0, 2154],
"kommentar": "getpoint Startpunkt der Kette - fuer die Testreihe auf X=0/Y=0 versetzt, damit die Ketten aller Linienzug-Tests nebeneinander auf einer Grundlinie entstehen statt verstreut. Unkritisch, weil dies der EINZIGE absolute Punkt des Skripts ist: alle weiteren Punkte sind relativ (point_rel mit dL/hz), die Geometrie also unveraendert. Z bleibt stehen - das ist die Starthoehe und ein echter Eingabewert."
},
{
"typ": "real",
+2 -2
View File
@@ -8,8 +8,8 @@
},
{
"typ": "point_abs",
"wert": [21377.904954, -10300, 2067],
"kommentar": "getpoint Startpunkt der Kette"
"wert": [20000.0, 0.0, 2067],
"kommentar": "getpoint Startpunkt der Kette - fuer die Testreihe auf X=20000/Y=0 versetzt, damit die Ketten aller Linienzug-Tests nebeneinander auf einer Grundlinie entstehen statt verstreut. Unkritisch, weil dies der EINZIGE absolute Punkt des Skripts ist: alle weiteren Punkte sind relativ (point_rel mit dL/hz), die Geometrie also unveraendert. Z bleibt stehen - das ist die Starthoehe und ein echter Eingabewert."
},
{
"typ": "real",