feat: VF-Linienzug Linie-GF - Separator VOR/NACH, Endpunkt/Zielhoehe-Vorwahl, steigende GF (Sonderfall bis 3 Grad)

Auf der neuen Kollegen-Architektur (Stufe 0-2: Spec/Journal/Replay-System
in vf_spec.lsp, Frage-Schale/Bauteil-Trennung) neu aufgebaut, nachdem der
urspruengliche Stand (Commit e76e24e) auf einer aelteren Basis beruhte und
per Rebase-Analyse als eigenstaendige, unabhaengige Erweiterung erkannt
wurde (der Kollege hat nichts entfernt - diese Features existierten vorher
nur lokal uncommitted).

Drei Erweiterungen fuer "Neue Linie: GF" in vf-linienzug-modus:
- Separator VOR/NACH direkt vor bzw. nach der Gefaellestrecke einfuegbar.
- Aeussere Vorwahl "Wie soll die Laenge bestimmt werden?": Endpunkt waehlen
  (bisheriges Verhalten) oder Zielhoehe zuerst festlegen (Winkel wird
  daraus berechnet).
- Dritte Option "Steigende GF" (Sonderfall, 0 bis 3 Grad): erlaubt eine GF,
  die statt zu fallen steigt. Neuer Helfer vfl-bogen-uebergang erkennt
  anhand der tatsaechlichen Frame-Neigung, ob 0/1/2 Uebergangsboegen
  (Vario_Bogen_auf_3/ab_3) noetig sind, und baut sie automatisch - im
  Normalfall (fallend->fallend) ein No-Op.

Lisp/vf_spec.lsp (Kollegen-Spec/Headless-Bau-System) um die drei neuen
Felder (laenge_modus/sep_vor/sep_nach/steigend_modus) erweitert, mit
Defaults, die alte Specs unveraendert lassen - haelt die "Spec-Pfad ==
interaktiver Pfad"-Invariante seines Systems (TEST_HUNDM05/VF_SPEC_BAU)
intakt. tests/test_vf_spec.lsp entsprechend mit neuen Testfaellen ergaenzt.

Neuer Regressionstest TEST_LINIENZUG_STUFE2 (linienzug_tests_stufe2.json)
sowie Anleitung doc/vf_linienzug_modus1_anleitung.md aus dem urspruenglichen
Commit uebernommen; die Gefaelle-Hoehe/Winkel-Optionsreihenfolge im
Testdatensatz an die jetzt geltende (Kollegen-)Konvention angepasst.

Offen (bewusst zurueckgestellt): lib/vf_spec_export.py (Python-Vorwaerts-
Emitter, Pendant zu vf_spec.lsp) noch nicht nachgezogen - siehe Folge-Commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Yuelin Wang
2026-09-11 14:18:31 +02:00
co-authored by Claude Sonnet 5
parent f4edb7339d
commit 23d653c4b3
8 changed files with 1092 additions and 148 deletions
+194
View File
@@ -0,0 +1,194 @@
# VF-Linienzug Modus 1 - Anleitung anhand eines realen Beispiels
Diese Anleitung erklaert Modus 1 des VF-Linienzugs ("Manuelle Eingabe",
`vf-linienzug-modus` in `Lisp/vf_linienzug.lsp`) nicht abstrakt, sondern
Schritt fuer Schritt anhand eines echten, in BricsCAD gebauten und
verifizierten Beispiels. Dasselbe Beispiel ist als automatisierter
Regressionstest hinterlegt: `tests/testdata/linienzug_tests_stufe2.json`,
aufrufbar in BricsCAD ueber `TEST_LINIENZUG_STUFE2` (siehe
`tests/test_linienzug.lsp`). Wer die Zahlen selbst nachvollziehen will, kann
diesen Testlauf jederzeit wiederholen.
Fuer die Architektur-Details (Frame-Kette, Journal/XDATA, Wizard-Dialoge)
siehe `doc/variofoerderer.md` und `doc/VarioFoerderer_Linienzug_Prinzipien.md`.
Diese Anleitung konzentriert sich auf die Bedienung und die typischen
Stolperfallen.
## 1. Was ist Modus 1?
Modus 1 baut eine VF-Linienzug-Kette **interaktiv, Element fuer Element**:
Sie klicken/geben nacheinander Punkte, Laengen, Winkel und Ja/Nein-
Entscheidungen ein, und jede Antwort erzeugt sofort ein Stueck Geometrie
(Umlenkstation, Gefaellestrecke, VF-Einheit, Vario-Kurve, ...). Das
unterscheidet Modus 1 von:
- **Modus 2** (Ziel-Hoehe-Modus): Sie zeichnen vorher einen Pfad (LINE/ARC-
Kette) und eine Zielhoehe, das Programm loest die Kette automatisch.
- **Modus 3** (Vorwaerts-Nachbau): rekonstruiert eine Kette aus einer
bestehenden Zeichnung (Legacy, wird umgebaut).
**Aufruf:** Befehl `FOERDERANLAGE` (bzw. `VarioFoerderer`) -> Anlagen-Typ
"Linienzug" waehlen -> Modus "1" (Manuelle Eingabe).
Jede Eingabe wird in einem Journal mitgeschrieben und als XDATA auf den
fertigen `VF_n`-Block geschrieben. Ein Abbruch (ESC) loescht dadurch nichts -
die bis dahin gebaute Teilkette bleibt als Block stehen und ist per
Doppelklick weiter bearbeitbar.
## 2. Das Beispiel im Ueberblick
Die Kette aus `linienzug_tests_stufe2.json` sieht so aus (Grundriss, von
oben betrachtet):
```
Start (Z=2154) --AS 90 links--> Horizontal-VF --Vario 90 rechts innen-->
--Horizontal-VF--> --Vario 90 rechts innen--> Linie-GF (3 Grad, Separator
vor+nach) --> Horizontal-VF --Vario 30 rechts innen--> Auf 27 Grad
--Vario 30 links aussen--> Kettenende (Motorstation + ES 90 links)
```
Kurz gesagt: die Kette startet auf Z=2154, macht zwei 90-Grad-Schwenks im
Grundriss, faellt ueber ein eigenstaendiges GF-Stueck (3 Grad) etwas ab,
steigt dann in einer zweiten VF-Einheit um 27 Grad wieder an, und muss am
Ende exakt auf die Starthoehe (2154mm) zurueckkommen. Genau dieser letzte
Schritt - der Rest-Hoehenausgleich passt zu keinem der Standard-Winkel mehr -
ist der interessante Teil (siehe Abschnitt 4, Stufe 1/Stufe 2).
## 3. Die Fragen der Reihe nach
Diese Tabelle zitiert die tatsaechlichen Konsolen-Fragen aus dem Testfall
(Kommentar-Spalte = `kommentar`-Feld im JSON) und erklaert, was jede Frage
bedeutet.
| # | Frage (sinngemaess) | Antwort im Beispiel | Bedeutung |
|---|---|---|---|
| 1 | Startpunkt der Kette | Klick (X/Y) | Beliebiger Punkt in der Zeichnung |
| 2 | Hoehe (Z) Startpunkt | 2154 | Absolute Einbauhoehe des Kettenanfangs |
| 3 | AS-Element setzen? | Ja | Umlenkstation am Anfang - "AS" = Ausgangs-/Anfangs-Element |
| 4 | AS-Element Winkel | 90 Grad | Baugroesse des Umlenkstations-Blocks (90 oder 30 Grad Kurvenradius) |
| 5 | AS-Seite | links | Auf welcher Seite die Umlenkstation seitlich ausschwenkt |
| 6 | Naechstes Element | Horizontal-VF | Kettenanfang-Menue hat 6 Optionen (GF-Bogen, Vario-Kurve, Linie-GF, Linie-VF, Horizontal-VF, Linienende) |
| 7 | Endpunkt Horizontal-VF | Klick | Laenge/Richtung der ersten VF-Einheit |
| 8 | Ziel-Hoehe Eingang GF1 | 1980 | Hoehe, auf die der Eingangs-GF-Anteil der VF-Einheit einregelt |
| 9 | Ist der Endpunkt der Foerderer? | Nein | Innerhalb der VF-Einheit: "geht die Kette hier zu Ende?" |
| 10-13 | Naechstes im VarioFoerderer -> Vario-Kurve 90 rechts innen | - | Grundriss-Schwenk INNERHALB der laufenden VF-Einheit |
| 14 | Ist der Endpunkt der Foerderer? | Nein | s.o. |
| 15-16 | Horizontaler Foerderer, Endpunkt | Klick | Weiteres gerades VF-Sub-Segment |
| 17 | Ist der Endpunkt der Foerderer? | Nein | s.o. |
| 18-21 | Vario-Kurve 90 rechts innen | - | Zweiter Grundriss-Schwenk |
| 22 | Ist der Endpunkt der Foerderer? | Ja, nur Motorstation | Schliesst die 1. VF-Einheit ab (Motorstation, kein ES) |
| 23 | Ist das Kettenende (ES-Element)? | Nein, weiterbauen | Nach der Motorstation: geht die Kette weiter? |
| 24 | Zusaetzlichen Separator hier? | Nein | Optionaler Separator direkt an der Motorstation |
| 25 | Naechstes Element | Neue Linie: GF | Jetzt folgt ein reines Gefaellestrecke-Element (kein VF) |
| 26 | Laenge bestimmen ueber | Endpunkt waehlen | Alternativ: Zielhoehe zuerst festlegen (siehe `vfl-gf-laenge-modus`) |
| 27 | Endpunkt Gefaellestrecke | Klick | Bestimmt deltaL der GF-Geraden |
| 28-29 | Separator VOR / NACH? | Ja / Ja | GF-Stuecke werden ueber Separatoren mechanisch begrenzt |
| 30-31 | Gefaelle festlegen -> Neigungswinkel | 3 Grad | Direkter Winkel (Alternative: Zielhoehe -> Winkel wird berechnet) |
| 32 | Ist das Kettenende? | Nein, weiterbauen | 3-Optionen-Menue: Ja+ES / Ja ohne ES / Nein |
| 33 | Naechstes Element | Horizontal-VF (2. Einheit) | Neue VF-Einheit beginnt direkt am GF-Ausgang (Separator als Eingang) |
| 34-49 | (wie oben: Vario-Kurven, Auf/Ab-Foerderer 27 Grad) | - | s.o. |
| 50 | Ist der Endpunkt der Foerderer? | Ja, Motorstation + Kettenende | Startet den automatischen Kettenende-Abschluss |
| 51-53 | ES-Element setzen? / Winkel / Seite | Ja / 90 / links | Ausgangs-Element, spiegelbildlich zum AS-Element |
| 54 | Endpunkt Kettenende | Klick | Letzter gewuenschter Punkt der Kette |
| 55 | Ziel-Hoehe Kettenende | 2154 | Muss wieder exakt die Starthoehe sein |
| 56 | (automatisch, keine Eingabe) | - | Stufe-1/Stufe-2-Loeser rechnet, siehe Abschnitt 4 |
| 57 | GF2=86mm unter Mindestlaenge - trotzdem bauen? | Ja | Sicherheitsfrage, siehe Abschnitt 4 |
**Wichtig zu Frage 9/14/17 ("Ist der Endpunkt der Foerderer?"):** Diese Frage
kommt IMMER, wenn Sie innerhalb einer laufenden VF-Einheit einen Punkt
gepickt haben. "Nein" heisst: der gepickte Punkt ist nur eine
Zwischen-Etappe, es geht in derselben VF-Einheit weiter (Vario-Kurve,
weiteres gerades Stueck, Auf/Ab). "Ja" beendet die VF-Einheit mit einer
Motorstation - optional zusaetzlich mit ES-Element (echtes Kettenende).
## 4. Stufe 1 / Stufe 2 - wie die letzte Strecke berechnet wird
Am Kettenende (Frage 55/56) ist die Aufgabe: von der aktuellen Position/
Hoehe zur gewuenschten Ziel-Hoehe kommen, UND dabei die feste Baugruppe
Motorstation + Separator (+ ES-Element, falls gewaehlt) unterbringen. Das
Programm versucht das in zwei Stufen (`vfl-winkel-stufe-entscheidung`,
`Lisp/vf_linienzug.lsp`):
- **Stufe 1 - Winkeltabelle:** Es probiert der Reihe nach die festen
Vario-Kurven-Winkel 3/6/9/12/15/18/21/27/33/39/45/51 Grad durch
(`berechne-alle-winkel`) und prueft, ob einer davon eine PASSENDE,
positive VF-Laenge ergibt. Das ist der Normalfall (siehe die Zeilen
"34-49" in der Tabelle: der Auf/Ab-Foerderer in der 2. VF-Einheit findet
so einen passenden Winkel, Auswahl-Index 8 = 27 Grad).
- **Stufe 2 - Horizontale Mitte + GF-Ausgleich:** Wenn KEIN Tabellenwinkel
passt (wie im Beispiel: alle 12 Kandidaten ergeben eine negative
VF-Laenge, die Reststrecke ist einfach zu kurz fuer einen echten
Vertikalbogen), rechnet `berechne-horizontale-mitte` eine andere Loesung:
ein HORIZONTALES VF-Stueck (winkel=0) plus eine kurze Gefaellestrecke
(GF2), die exakt den fehlenden Hoehenunterschied ausgleicht. Im Beispiel:
GF2=86mm, VF=286mm.
Die Formel dahinter ist simpel und lohnt sich zu verinnerlichen: bei einem
FESTEN Neigungswinkel von 3 Grad braucht ein Hoehenausgleich von `H`
Millimetern eine GF-Laenge von `H / tan(3 Grad) ~= H * 19`. Ein winziger
Hoehenrest von z.B. 49mm braucht demnach bereits ~935mm GF-Laenge - siehe
Abschnitt 5.a. GF2 im Beispiel (86mm) ist kuerzer als die uebliche
Mindestlaenge (400mm, `*vfl-gf-min-laenge*`) - deshalb die Rueckfrage in
Schritt 57 ("trotzdem mit 86mm bauen?"). "Ja" baut trotzdem exakt mit dem
berechneten Wert; "Nein" wuerde den bis dahin gebauten Teil verwerfen (siehe
`vfl-loesche-seit`/`vfl-modus-abbruch-sichern`).
**Merksatz:** Stufe 1 sucht einen "sauberen" Standard-Winkel; Stufe 2 ist
der Rettungsanker, wenn dafuer schlicht nicht genug Platz ist - er tauscht
einen Vertikalbogen gegen "flach + minimaler GF-Ausgleich".
## 5. Typische Stolperfallen
### a) Gefaellestrecke (GF) ist "laengenhungrig" bei 3 Grad
3 Grad ist ein SEHR flacher Winkel. `tan(3 Grad) ~= 0.0524`, also braucht
jeder Millimeter Hoehenunterschied ungefaehr **19mm** Laenge:
```
Laenge = Hoehendifferenz / tan(3 Grad) ~= Hoehendifferenz * 19
```
Wer nur wenige mm bis cm Hoehenunterschied ausgleichen will, bekommt damit
schnell GF-Laengen im halben bis ganzen Meterbereich. Das ist die haeufigste
Ursache fuer "die Reststrecke ist zu kurz"-Meldungen und fuer den
Stufe-2-Fallback aus Abschnitt 4. Falls eine GF partout nicht passt: entweder
mehr Grundriss-Laenge einplanen, oder pruefen, ob ein Vertikalbogen
(Vario-Kurve mit groesserem Winkel, siehe Stufe 1) die bessere Wahl ist.
### b) Motorstation + Separator + ES-Element haben einen FESTEN Fussabdruck
Am Kettenende ist nicht die ganze gepickte Reststrecke frei verfuegbar -
ein fester Anteil ist fuer Motorstation und Separator reserviert
(`*vfk-feste-horizontal-kettenende*` = 800mm = 500mm Motorstation + 300mm
Separator), und falls zusaetzlich ein ES-Element gewaehlt wird, kommt dessen
eigener Fussabdruck (abhaengig von 30/90 Grad Bauform) noch oben drauf. Wer
diese festen 800mm (+ ES) nicht einplant, landet schnell bei einer negativen
"freien" Reststrecke - genau der Fall, der in Abschnitt 4 den Stufe-2-
Fallback ausloest.
### c) Seitlicher Versatz bei 90-Grad-AS/ES-Elementen ist NORMAL
Ein AS- oder ES-Element mit 90 Grad Bauform dreht die Fahrtrichtung nicht
einfach "auf der Stelle" - sein Block hat eine reale Baugroesse mit einem
seitlichen (quer zur Fahrtrichtung liegenden) Versatz. Im Standard-Testfall
(`linienzug_tests.json`) betraegt dieser Versatz ca. 637mm (`dY`), im
Stufe-2-Testfall ca. 638mm (`dX`, da die Fahrtrichtung dort anders liegt).
**Das ist kein Baufehler** - es ist die tatsaechliche Geometrie des
90-Grad-ES/AS-Blocks. Ein "Ist-Ziel-Report" mit einer Restabweichung von
ca. 638mm quer zur letzten Fahrtrichtung, aber ~0mm in Laengs-/Hoehenrichtung,
ist ein KORREKTES Ergebnis, keine Abweichung, die weiter untersucht werden
muss.
## 6. Nachvollziehen / Nachbauen
- Live in BricsCAD: `FOERDERANLAGE` -> Linienzug -> Modus 1, und die
Eingaben aus der Tabelle in Abschnitt 3 der Reihe nach eintippen/klicken.
- Automatisiert (ohne Klicks): Befehl `TEST_LINIENZUG_STUFE2` (nach Laden
von `tests/test_linienzug.lsp`) spielt exakt dieselbe Sequenz aus
`tests/testdata/linienzug_tests_stufe2.json` ab und meldet das
Ist-Ziel-Ergebnis in der Konsole.
- Debug-Log: mit `dbgopen`/dem zentralen Debug-Schalter (siehe
`Lisp/ssg_dbg.lsp`) lassen sich alle `GEOMETRIE:`/`GEOMETRIE ERFOLG:`-
Zeilen in eine `.dbg`-Datei im Log-Verzeichnis mitschreiben - hilfreich,
um genau wie in diesem Beispiel eine reale Sitzung nachtraeglich in
einen Testfall zu verwandeln.