From 0f1c7d2edfd501f77034991be2baa4eecf7e3674 Mon Sep 17 00:00:00 2001 From: Yuelin Wang Date: Sat, 12 Sep 2026 00:38:15 +0200 Subject: [PATCH] feat: "Neue Linie BIS Kettenende" erkennt VF/GF-Startpunkt Bei "Neue Linie BIS Kettenende" (Option 6) wird jetzt erkannt, ob der Startpunkt zu einer bestehenden VF- oder GF-Kette gehoert (KS_AUS-Scan am Kettenanfang bzw. letzter-typ bei laufender Fortsetzung) und die Bau-Logik entsprechend verzweigt, statt immer die generische Machbarkeits-Automatik zu fragen: - VF erkannt: baut zwingend ueber die Stufe-1/Stufe-2-Diagnose (vfl-vf-entscheidung), auch wenn der natuerliche Winkel zufaellig nahe 3 Grad liegt (vfl-segment-entscheidung haette dort faelschlich eine reine GF gewaehlt) - GF erkannt: neue Unterfrage mit denselben 2 Optionen wie "Neue Linie: GF" (Zielhoehe fest -> Laenge berechnen, ODER Laenge fest -> Winkel berechnen), eigener Radiobutton-Dialog (Wiederverwendung von vflw-gruppe-gf-steigend-untermodus-impl) - nicht eindeutig zuordenbar (z.B. frischer AS-Element-Start): bisherige automatische Entscheidung unveraendert Neue Helfer: vfl-letzter-typ-familie (Pendant zu vfl-kette-typ-familie fuer den session-lokalen letzter-typ-String). Co-Authored-By: Claude Sonnet 5 --- Lisp/vf_linienzug.lsp | 110 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index 3915427..477ed98 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -4428,6 +4428,19 @@ ) ) +;; Wie vfl-kette-typ-familie, aber fuer den SESSION-LOKALEN "letzter-typ"- +;; String (statt eines per Blockname erkannten XDATA-Typs) - fuer eine +;; laufende Fortsetzung (kettenanfang=nil) ist der Vorgaengertyp bereits +;; ohne KS_AUS-Scan bekannt. "Separator" zaehlt als GF-Familie (er folgt in +;; diesem Ablauf immer auf ein GF-Segment, siehe "Linie-GF"-Zweig). +(defun vfl-letzter-typ-familie (letzter-typ) + (cond + ((member letzter-typ '("VF" "Vario-Kurve")) "VF") + ((member letzter-typ '("GF" "Separator")) "GF") + (t nil) + ) +) + ;; Eingang-Modus + L_GF-Stumpf fuer eine neue VF-Einheit bestimmen - EINE ;; gemeinsame Entscheidung fuer "Neue VF mit horizontalem Anfang" UND "Neue ;; Linie: Ab/Auf VF" (Punkt 5). Reihenfolge: @@ -4827,7 +4840,8 @@ gf-laenge-modus gf-steigend-modus sep-vor-gf sep-nach-gf sep-anzahl erg-bogen vf-eingang-lgf vf-eingang-modus eingang-laenge winkel-hoehen-erg - bogen-mass fest-drop fest-laenge eingang-fertig) + bogen-mass fest-drop fest-laenge eingang-fertig + linie-ende-familie linie-ende-untermodus) ;; "Zurueck"/"Abbrechen"-Flag ganz am Anfang zuruecksetzen (auch schon vor ;; der ersten Praeambel-Frage) - sonst wuerde ein von einem VORHERIGEN Lauf ;; noch gesetztes Flag (z.B. nach "Abbrechen") den allerersten vfl-in-*- @@ -5771,7 +5785,12 @@ ) ) - ((= wahl "Linie") ;; --- Neue Linie BIS Kettenende (automatische GF/VF-Entscheidung, unveraendert) --- + ((= wahl "Linie") ;; --- Neue Linie BIS Kettenende --- + ;; GF/VF-Entscheidung: wird der Startpunkt eindeutig einer bestehenden + ;; VF- oder GF-Kette zugeordnet (linie-ende-familie, siehe unten), + ;; entscheidet DAS die Bau-Logik (Stufe-1/2-Diagnose bzw. Endpunkt/ + ;; Zielhoehe-Wahl) - nur wenn nicht eindeutig, greift weiterhin die + ;; automatische Machbarkeits-Entscheidung (vfl-segment-entscheidung). ;; Fahrtrichtung folgt dem vorherigen Element (Frame); nur das erste ;; Segment (frame=nil) definiert die Richtung frei. (setq linie-mess (vfl-neue-linie-messen p-aktuell @@ -5779,6 +5798,25 @@ (if (null linie-mess) (progn (princ (ssg-text "vfl-abgebrochen")) (exit))) (setq deltaL (car linie-mess) hz-neu (cadr linie-mess)) (setq kettenanfang (null frame)) + ;; Startpunkt-Typ erkennen (VF/GF/nicht eindeutig): bei einer + ;; laufenden Fortsetzung ist der Vorgaengertyp schon bekannt + ;; (letzter-typ); am echten Kettenanfang OHNE AS-Element wird wie bei + ;; vfl-eingang-modus-bestimmen per KS_AUS-Scan erkannt, ob der + ;; gepickte Startpunkt auf einer bestehenden VF- oder GF-Kette liegt. + ;; Steht schon ein AS-Element (as-vorhanden), ist der Anfang per + ;; Definition neutral/nicht zuordenbar - dann bleibt die generische + ;; Automatik (vfl-segment-entscheidung) unten aktiv. Genutzt weiter + ;; unten, um bei erkannter Familie NICHT die generische Automatik zu + ;; fragen, sondern direkt die passende (VF: Stufe-1/2-Diagnose; GF: + ;; Endpunkt/Zielhoehe-Wahl wie "Neue Linie: GF") Logik zu verwenden. + (setq linie-ende-familie + (if kettenanfang + (if (not as-vorhanden) + (progn + (setq erg (vfl-ks-aus-hz-an-punkt p-aktuell)) + (if erg (vfl-kette-typ-familie (cdr erg)) nil)) + nil) + (vfl-letzter-typ-familie letzter-typ))) (if (< deltaL 1.0) (princ (ssg-text "vfl-fehler-linie-zu-kurz")) (progn @@ -5856,9 +5894,71 @@ (list (rtos deltaL 2 0) (rtos deltaH 2 0)))) ) ) - (setq entscheidung (vfl-segment-entscheidung deltaL deltaH richtung)) - (setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung) - L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung)) + (cond + ;; --- Startpunkt als VF-Familie erkannt --- + ;; IMMER ueber die Stufe-1/Stufe-2-Diagnose bauen (auch + ;; wenn der natuerliche Winkel zufaellig nahe 3 Grad + ;; liegt) - vfl-segment-entscheidung wuerde in dem Fall + ;; faelschlich eine reine GF waehlen, obwohl der + ;; Vorgaenger eindeutig eine VF-Kette ist. + ((equal linie-ende-familie "VF") + (setq entscheidung (vfl-vf-entscheidung deltaL deltaH richtung)) + (setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung) + L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung))) + ;; --- Startpunkt als GF-Familie erkannt --- + ;; Dieselbe Endpunkt-/Zielhoehe-Wahl wie "Neue Linie: GF" + ;; (Zweig A/B) statt der generischen Automatik - eine + ;; reine Gefaellestrecke kann nicht steigen. + ((equal linie-ende-familie "GF") + ;; Stufe-2-Diagnosevariablen zuruecksetzen: dieser Zweig + ;; ruft vfl-vf-entscheidung NICHT auf, ein evtl. noch + ;; von einem frueheren Versuch gesetzter Text/Vorschlag + ;; darf bei einem hier fehlschlagenden GF-Segment nicht + ;; faelschlich mit angezeigt werden (siehe gemeinsamer + ;; "typ=nil"-Meldungsblock unten). + (setq *vfl-stufe2-diagnose-text* nil) + (setq *vfl-stufe2-minl-vorschlag* nil *vfl-stufe2-minh-vorschlag* nil) + (if (= richtung "Auf") + (setq typ nil) + (progn + (princ (ssg-text "vfl-gf-laenge-modus-header")) + (princ (ssg-text "vfl-gf-laenge-modus-opt-endpunkt")) + (princ (ssg-text "vfl-gf-laenge-modus-opt-hoehe")) + (if (vfl-wizard-aktiv) + (vl-catch-all-apply 'vflw-gruppe-gf-steigend-untermodus-impl nil)) + (setq linie-ende-untermodus + (vfl-menu (ssg-text "prompt-wahl-1-2") + (list (ssg-text "vfl-gf-laenge-modus-opt-endpunkt") + (ssg-text "vfl-gf-laenge-modus-opt-hoehe")) 1 + "vfl-gf-laenge-modus-header")) + (if (= linie-ende-untermodus "2") + ;; Zielhoehe fest, Winkel fix *vfk-gefaelle-winkel* + ;; -> Laenge wird daraus berechnet (ersetzt die + ;; oben gemessene/reservierte deltaL). + (progn + (setq winkel *vfk-gefaelle-winkel*) + (setq deltaL + (/ deltaH (/ (sin (* winkel (/ pi 180.0))) (cos (* winkel (/ pi 180.0)))))) + (if (< deltaL 1.0) + (setq typ nil) + (setq typ "GF" L_GF nil L_VF nil))) + ;; Endpunkt (deltaL) fest, Winkel aus deltaL + + ;; Zielhoehe berechnen. + (progn + (setq winkel (* (atan (/ deltaH deltaL)) (/ 180.0 pi))) + (if (> winkel *vfk-gefaelle-winkel*) + (setq typ nil) + (setq typ "GF" L_GF nil L_VF nil))) + ) + ) + ) + ) + ;; --- Nicht eindeutig zuordenbar: bisherige Automatik --- + (t + (setq entscheidung (vfl-segment-entscheidung deltaL deltaH richtung)) + (setq typ (nth 0 entscheidung) winkel (nth 1 entscheidung) + L_GF (nth 2 entscheidung) L_VF (nth 3 entscheidung))) + ) ) )