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
+46 -7
View File
@@ -49,6 +49,12 @@
(setq *vsp-tab-seite* '(("links" . "1") ("rechts" . "2")))
(setq *vsp-tab-variante* '(("aussen" . "1") ("innen" . "2")))
(setq *vsp-tab-gefaelle* '(("hoehe" . "1") ("winkel" . "2")))
;; Vorwahl "Wie soll die Laenge der Gefaellestrecke bestimmt werden?"
;; (vfl-menu in vf-linienzug-modus, wahl="Linie-GF"). Die innere Wahl im
;; Steigend-Sonderfall (Endpunkt/Hoehe) nutzt dieselbe Tabelle - dort sind
;; nur die Codes "1"/"2" gueltig, "steigend" kommt dort nie vor.
(setq *vsp-tab-gf-laenge-modus* '(("endpunkt" . "1") ("hoehe" . "2")
("steigend" . "3")))
(setq *vsp-tab-verteilung* '(("haelfte" . "1") ("einlauf" . "2")))
(setq *vsp-tab-im-vf* '(("horizontal" . "1") ("vario-kurve" . "2")
("auf-ab" . "3")))
@@ -219,7 +225,7 @@
(vsp-wert-str (ssg-val kopf "as_winkel") "as_winkel")
(vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite"))))
(defun vsp-sektion (sek subs erster / label tab code art)
(defun vsp-sektion (sek subs erster / label tab code art modus smodus)
(setq label (ssg-val sek "glied"))
(setq *vsp-wo* (strcat "Sektion " (if label label "(ohne glied)")))
(cond
@@ -250,12 +256,45 @@
(vsp-code-raus *vsp-tab-seite* (ssg-val sek "seite") "seite"))
((= label "Linie-GF")
(vsp-linie sek)
(setq art (ssg-val sek "gefaelle"))
(vsp-code-raus *vsp-tab-gefaelle* art "gefaelle")
(if (= art "hoehe")
(vsp-zahl "REAL" (ssg-val sek "hoehe") "hoehe")
(vsp-zahl "REAL" (ssg-val sek "winkel") "winkel"))
;; Vorwahl "laenge_modus" (endpunkt/hoehe/steigend, Default
;; "endpunkt" - deckt alte Specs ohne dieses Feld ab, identisch
;; zum bisherigen alleinigen Ablauf). "steigend" ist der
;; Sonderfall (GF bis 3 Grad steigend, KEIN Separator, eigene
;; innere Endpunkt/Hoehe-Wahl "steigend_modus"). Die DL(+hz)-
;; Eingabe (vsp-linie) faellt bei "hoehe"/"steigend"+"hoehe" NUR
;; beim allerersten Segment der Kette an (Kettenanfang braucht
;; einen Pick fuer die freie Richtung; jedes weitere Segment erbt
;; die Richtung vom Vorgaenger ohne eigenen Pick) - siehe erster.
(setq modus (ssg-val sek "laenge_modus"))
(if (null modus) (setq modus "endpunkt"))
(vsp-code-raus *vsp-tab-gf-laenge-modus* modus "laenge_modus")
(cond
((= modus "steigend")
(setq smodus (ssg-val sek "steigend_modus"))
(if (null smodus) (setq smodus "endpunkt"))
(vsp-code-raus *vsp-tab-gf-laenge-modus* smodus "steigend_modus")
(if (= smodus "endpunkt")
(vsp-linie sek)
(if erster (vsp-linie sek)))
(if (= smodus "hoehe")
(vsp-zahl "REAL" (ssg-val sek "hoehe") "hoehe"))
(vsp-zahl "REAL" (ssg-val sek "winkel") "winkel"))
((= modus "hoehe")
(if erster (vsp-linie sek))
(vsp-raus "STR" (vsp-ja-code (ssg-val sek "sep_vor")))
(vsp-raus "STR" (vsp-ja-code (ssg-val sek "sep_nach")))
(vsp-zahl "REAL" (ssg-val sek "hoehe") "hoehe")
(vsp-zahl "REAL" (ssg-val sek "winkel") "winkel"))
(T ;; "endpunkt"
(vsp-linie sek)
(vsp-raus "STR" (vsp-ja-code (ssg-val sek "sep_vor")))
(vsp-raus "STR" (vsp-ja-code (ssg-val sek "sep_nach")))
(setq art (ssg-val sek "gefaelle"))
(vsp-code-raus *vsp-tab-gefaelle* art "gefaelle")
(if (= art "hoehe")
(vsp-zahl "REAL" (ssg-val sek "hoehe") "hoehe")
(vsp-zahl "REAL" (ssg-val sek "winkel") "winkel")))
)
(vsp-code-raus *vsp-tab-ende3* (ssg-val sek "ende") "ende"))
((= label "Linie-VF")