feat: VF-Hoehe je Segment (Sivas 4433-4437) + AS-Zufuehrungsachse bei 30 Grad
Zwei Themen, die dieselben Dateien beruehren und daher zusammen gehen.
1) VF_HOEHE_m - Hoehe je VF-Segment, Sivas-Merkmale 4433-4437
Sivas erwartet je Streckengruppe bis zu fuenf Variofoerderer-Hoehen.
Neues Block-Attribut VF_HOEHE_m: kommagetrennte Liste in Metern mit 3
Nachkommastellen, Eintrag fuer Eintrag parallel zu L_VF_m/VF_WINKEL.
Je Eintrag der Mittelwert aus KS_EIN und KS_AUS DES GERADEN VF-Abschnitts.
Zwischen Umlenk- und Motorstation koennen mehrere Abschnitte liegen
(auf/ab/horizontal), jeder bekommt einen eigenen Wert.
SONDERFALL Standard/Etage: dort gibt es nur einen Motor und nur einen
geraden Abschnitt - gemessen wird die GANZE Kette (AS-KS_EIN bis
ES-KS_AUS, vf-vfhoehe-kette). Das ersetzt den Segmentwert; der Linienzug
laeuft nicht durch vf-dialog-berechnen-einfuegen und behaelt seine Liste.
WICHTIG - vollstaendige Erfassung: die VF-Segmente entstehen NICHT alle in
vfs-vf-koerper. Horizontale Zwischenstuecke, das "schon flach"-Segment und
die Modus-2/3-Fuellstuecke bauen direkt mit insert-inclined-scaled-block,
die Kette-Merge-Rekonstruktion liest sie aus bestehenden Bloecken. Ein
erster Fix nur in vfs-vf-koerper lieferte darum zu wenige Werte (realer
Befund: L_VF_m hatte drei Eintraege, VF_HOEHE_m einen). Jetzt sind alle 14
Stellen erfasst, die vfl-acc-vf-seg aufrufen - dafuer das Paar
vf-vfhoehe-merke/-schliesse, das ohne lokale Variable auskommt.
REGEL (im Code dokumentiert): Jede Stelle, die vfl-acc-vf-seg aufruft,
MUSS auch eine Hoehe erfassen - sonst verschiebt sich die Liste gegen
L_VF_m und im Export landet eine Hoehe beim falschen Foerderer.
Formatierung ueber vf-meter-3: (rtos x 2 3) allein kuerzt je nach DIMZIN
nachfolgende Nullen ("2.5" statt "2.500", "-1" statt "-1.000") - im
Testlauf real aufgetreten.
Attribut-Schema *strecke-attr-gruppe* (ssg_core.lsp) ergaenzt, sonst
verschluckt ssg-attrib-set-on den neuen Tag stillschweigend.
export_sivas.py verteilt die Liste auf VF_HOEHE_MERKMALE (4433-4437);
ueberzaehlige Abschnitte werden weggelassen statt zusammengefasst, fehlende
lassen das Merkmal ganz weg.
2) AS-Element 30 Grad: Zufuehrungsachse statt Seitenwahl
Der Startpunkt einer Kette mit AS-Element ist geometrisch keine Position,
sondern eine ACHSE: das AS sitzt an einer durchlaufenden Strecke und
schleust daraus aus, seine KS_EIN-Achse muss darauf liegen. Bisher richtete
vfl-insert-as-element das KS_AUS entlang der Kettenrichtung aus, wodurch
das KS_EIN um den Blockschwenk verdreht stand - beim 90-Grad-Element kaum
sichtbar, beim 30-Grad-Element deutlich.
Beim 30-Grad-Element wird die Seitenauswahl im AS-Gruppendialog jetzt
ausgegraut; stattdessen gibt ein zweiter Punkt die Zufuehrungsrichtung
(der Startpunkt bleibt der Sitz des Elements). Die Seite folgt aus der Lage
des naechsten Kettenpunkts zur Achse (vfl-seite-aus-lage). 90 Grad bleibt
unveraendert bei der Seitenfrage.
Der Dialog legt bei 30 Grad bewusst KEINE Seite mehr in die Pending-Queue -
sonst zog die nachfolgende Punktfrage sie als vermeintlichen Punkt heraus
und erschien gar nicht (realer Fehler beim ersten Test).
Abwaertskompatibilitaet: aeltere 30-Grad-Ketten wurden noch MIT Seitenfrage
gebaut. vfl-replay-peek-art sieht beim Replay nach, was tatsaechlich
ansteht ("PT" = Achse, "STR" = Seite) - die Modus-Wahl selbst wird nicht
journalisiert, weil sie daraus eindeutig rekonstruierbar ist.
Unit-Suite 687/687 gruen. VF-Hoehe in BricsCAD bestaetigt. Die AS-Achsenfrage
ist dort noch NICHT gelaufen, seit die Seitenauswahl ausgegraut wird.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1264,6 +1264,13 @@
|
||||
("L_VF_m" "0.000")
|
||||
("ANTRIEBFAHRTRICHTUNG" "Auf")
|
||||
("VF_WINKEL" "0")
|
||||
;; Hoehe je VF-SEGMENT in Metern (3 Nachkommastellen), kommagetrennt und
|
||||
;; Eintrag fuer Eintrag parallel zu L_VF_m/VF_WINKEL: Mittelwert aus KS_EIN
|
||||
;; und KS_AUS des jeweiligen geraden VF-Abschnitts (vf-vfhoehe-segment in
|
||||
;; vf_core.lsp, erfasst in vfs-vf-koerper). Zwischen Umlenk- und
|
||||
;; Motorstation koennen mehrere Abschnitte liegen (auf/ab/horizontal).
|
||||
;; Sivas-Merkmale 4433-4437 (bis zu fuenf Abschnitte je Gruppe).
|
||||
("VF_HOEHE_m" "0.000")
|
||||
("VF_Bogen_A_90" "0")
|
||||
("VF_Bogen_A_60" "0")
|
||||
("VF_Bogen_A_30" "0")
|
||||
|
||||
@@ -218,6 +218,102 @@
|
||||
(defun vf-motorseite-aktuell ( / )
|
||||
(if (member *vf-motorseite* '("links" "rechts")) *vf-motorseite* "rechts"))
|
||||
|
||||
;; ============================================================
|
||||
;; VF-HOEHE JE SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437)
|
||||
;; ============================================================
|
||||
;; Sivas erwartet je Streckengruppe bis zu fuenf Variofoerderer-Hoehen. Ein
|
||||
;; Eintrag gehoert zu EINEM VF-Segment (Koerper) - nicht zu einer ganzen
|
||||
;; Foerdereinheit und nicht zur ganzen Kette (Nutzer-Korrektur 2026-10-21):
|
||||
;;
|
||||
;; Hoehe = Mittelwert aus KS_EIN und KS_AUS DIESES Segments.
|
||||
;;
|
||||
;; Eine Kette, die durch Vario-Boegen in drei Abschnitte geteilt ist, bekommt
|
||||
;; dadurch drei Werte - die Liste laeuft Eintrag fuer Eintrag parallel zu
|
||||
;; L_VF_m, VF_WINKEL und ANTRIEBFAHRTRICHTUNG.
|
||||
;;
|
||||
;; Erfasst wird an genau EINER Stelle: vfs-vf-koerper baut ein Segment, kennt
|
||||
;; dessen KS_EIN als Eingangspunkt und liefert dessen KS_AUS zurueck. Alle
|
||||
;; Modi (Standard, Etage, Linienzug) bauen ihre VF-Koerper darueber, deshalb
|
||||
;; muss der verzweigte Bau-Pfad selbst nicht angefasst werden.
|
||||
;;
|
||||
;; Einheit: Meter mit 3 Nachkommastellen (wie L_VF_m), kommagetrennt ueber
|
||||
;; vfl-join-komma - Reihenfolge = Bau-Reihenfolge.
|
||||
(if (not (boundp '*vf-acc-vfhoehe*)) (setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
(defun vf-vfhoehe-reset ()
|
||||
(setq *vf-acc-vfhoehe* '()))
|
||||
|
||||
;; Ein VF-Segment erfassen: z-ein = Z des KS_EIN, z-aus = Z des KS_AUS (mm).
|
||||
;; Fehlt einer der Werte, wird NICHTS angehaengt - sonst verschoebe sich die
|
||||
;; Liste gegen L_VF_m/VF_WINKEL und im Export landete eine Hoehe beim falschen
|
||||
;; Foerderer.
|
||||
(defun vf-vfhoehe-segment (z-ein z-aus)
|
||||
(if (and (numberp z-ein) (numberp z-aus))
|
||||
(setq *vf-acc-vfhoehe*
|
||||
(append *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-ein z-aus) 2.0)))))))
|
||||
|
||||
;; Bequemes Paar fuer die Bau-Pfade: vor dem Einbau den Startpunkt merken,
|
||||
;; danach mit dem Endpunkt abschliessen. Beide geben ihren Punkt zurueck,
|
||||
;; lassen sich also ohne zusaetzliche lokale Variable einsetzen:
|
||||
;;
|
||||
;; (vf-vfhoehe-merke pt)
|
||||
;; (setq pt (insert-inclined-scaled-block ...))
|
||||
;; (vf-vfhoehe-schliesse pt)
|
||||
;;
|
||||
;; Noetig, weil die VF-Segmente NICHT alle ueber vfs-vf-koerper laufen: die
|
||||
;; horizontalen Zwischenstuecke und die Modus-2-Fuellstuecke bauen direkt mit
|
||||
;; insert-inclined-scaled-block. Wurde dort nicht erfasst, fehlten ihre
|
||||
;; Hoehen und VF_HOEHE_m war kuerzer als L_VF_m (realer Befund 2026-10-21:
|
||||
;; L_VF_m hatte drei Eintraege, VF_HOEHE_m nur einen).
|
||||
;;
|
||||
;; REGEL: Jede Stelle, die (vfl-acc-vf-seg ...) aufruft, MUSS auch eine Hoehe
|
||||
;; erfassen - sonst verschiebt sich die Liste gegen L_VF_m/VF_WINKEL und im
|
||||
;; Sivas-Export landet eine Hoehe beim falschen Foerderer.
|
||||
(if (not (boundp '*vf-vfhoehe-merk*)) (setq *vf-vfhoehe-merk* nil))
|
||||
|
||||
(defun vf-vfhoehe-merke (pt)
|
||||
(setq *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
pt)
|
||||
|
||||
(defun vf-vfhoehe-schliesse (pt)
|
||||
(vf-vfhoehe-segment *vf-vfhoehe-merk* (if (listp pt) (caddr pt) nil))
|
||||
(setq *vf-vfhoehe-merk* nil)
|
||||
pt)
|
||||
|
||||
;; SONDERFALL Standard/Etage: Hoehe ueber die GANZE Kette.
|
||||
;;
|
||||
;; Diese beiden Typen haben nur EINEN Motor und nur EINEN geraden
|
||||
;; VF-Abschnitt (Nutzer-Vorgabe 2026-10-21). Statt des Segmentwerts gilt dort
|
||||
;; der Mittelwert der ganzen Anlage:
|
||||
;; Anfang = KS_EIN des AS-Elements (Startpunkt der Anlage)
|
||||
;; Ende = KS_AUS des ES-Elements (Rueckgabewert der Einfuegefunktion)
|
||||
;;
|
||||
;; ERSETZT die Liste bewusst, statt anzuhaengen: vfs-vf-koerper hat beim Bau
|
||||
;; bereits den Segmentwert gesammelt, der hier nicht gelten soll. Ergebnis ist
|
||||
;; genau ein Eintrag.
|
||||
;;
|
||||
;; Gerechnet wird aus der GEBAUTEN Geometrie, nicht aus der Soll-Vorgabe
|
||||
;; (anders als MONTAGEHOEHE_m, dessen hoehe-bis aus deltaH abgeleitet ist).
|
||||
;; Beide Hoehen in mm.
|
||||
(defun vf-vfhoehe-kette (z-anfang z-ende)
|
||||
(if (and (numberp z-anfang) (numberp z-ende))
|
||||
(setq *vf-acc-vfhoehe* (list (vf-meter-3 (/ (+ z-anfang z-ende) 2.0))))
|
||||
(setq *vf-acc-vfhoehe* '())))
|
||||
|
||||
;; Millimeter -> Meter als String mit GENAU 3 Nachkommastellen.
|
||||
;;
|
||||
;; (rtos x 2 3) allein genuegt nicht: je nach DIMZIN schneidet es nachfolgende
|
||||
;; Nullen ab und liefert "2.5" statt "2.500" bzw. "-1" statt "-1.000" (real
|
||||
;; beobachtet im Testlauf). Fuer eine Merkmalsliste ist die feste Stellenzahl
|
||||
;; aber gewollt, darum wird hier aufgefuellt - unabhaengig von der
|
||||
;; Zeichnungseinstellung.
|
||||
(defun vf-meter-3 (mm / s pos)
|
||||
(setq s (rtos (/ (float mm) 1000.0) 2 3))
|
||||
(if (not (vl-string-search "." s)) (setq s (strcat s ".")))
|
||||
(setq pos (vl-string-search "." s))
|
||||
(while (< (- (strlen s) pos 1) 3) (setq s (strcat s "0")))
|
||||
s)
|
||||
|
||||
;; ============================================================
|
||||
;; TEIL 5: KS_EIN/KS_AUS EXTRAKTION
|
||||
;; ============================================================
|
||||
@@ -977,6 +1073,9 @@
|
||||
(cons "L_VF_m" (rtos (/ L_VF 1000.0) 2 3))
|
||||
(cons "ANTRIEBFAHRTRICHTUNG" richtung)
|
||||
(cons "VF_WINKEL" (itoa best-winkel))
|
||||
;; Hoehe der (einen) Foerdereinheit - beim Standard-/Etage-Typ
|
||||
;; fuellen vfs-vf-entry/-exit genau einen Listeneintrag.
|
||||
(cons "VF_HOEHE_m" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(cons "ANZAHL_SEPARATOR" "2")
|
||||
(cons "ANZAHL_SCANNER" (itoa n-scanner))
|
||||
(cons "GERUEST_EINZELMODUL" geruest-einzelmodul)
|
||||
@@ -1013,6 +1112,10 @@
|
||||
horizontal-info winkelwahl best-winkel L_GF L_VF L_GF1 L_GF2
|
||||
verteilung-modus n-scanner hoehe-von hoehe-bis lastEnt
|
||||
vf-insert vf-endpunkt staustrecke-basis)
|
||||
;; VF-Hoehen-Akkumulator pro Anlage zuruecksetzen - sonst erbte die naechste
|
||||
;; Anlage die Hoehen der vorherigen. (Im Linienzug erledigt das
|
||||
;; vfl-acc-reset; Standard/Etage laufen nicht darueber.)
|
||||
(vf-vfhoehe-reset)
|
||||
(setq berechne-fn (vf-registry-berechne-fn typ))
|
||||
(setq einfuege-fn (vf-registry-einfuege-fn typ))
|
||||
(setq ergebnis (apply berechne-fn (list deltaL deltaH richtung seite)))
|
||||
@@ -1064,6 +1167,15 @@
|
||||
(setq vf-endpunkt
|
||||
(apply einfuege-fn
|
||||
(list deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)))
|
||||
;; VF_HOEHE_m fuer Standard/Etage: Mittelwert ueber die GANZE Kette
|
||||
;; (AS-KS_EIN = startpunkt, ES-KS_AUS = Rueckgabe der Einfuegefunktion),
|
||||
;; weil es hier nur einen Motor und nur einen geraden VF-Abschnitt
|
||||
;; gibt. Ersetzt den beim Bau gesammelten Segmentwert - siehe
|
||||
;; vf-vfhoehe-kette. Der Linienzug laeuft NICHT hier durch und behaelt
|
||||
;; daher seine Segmentliste.
|
||||
(vf-vfhoehe-kette (caddr startpunkt)
|
||||
(if (and vf-endpunkt (listp vf-endpunkt))
|
||||
(caddr vf-endpunkt) nil))
|
||||
(setq vf-insert
|
||||
(vf-block-erstellen typ seite vf-nummer n-scanner
|
||||
hoehe-von hoehe-bis deltaH deltaL L_VF L_GF1 L_GF2
|
||||
|
||||
+206
-9
@@ -82,7 +82,12 @@
|
||||
;; sichern): nil (normal) / "zurueck" (letztes Glied verwerfen und neu
|
||||
;; fragen) / "abbrechen" (Bau hier stoppen, Baustand bleibt stehen).
|
||||
*vfl-wizard-abbruch-grund* nil
|
||||
*vfl-abbruch-letztes-ent* nil))
|
||||
*vfl-abbruch-letztes-ent* nil)
|
||||
;; VF-Hoehen je SEGMENT (Attribut VF_HOEHE_m, Sivas 4433-4437).
|
||||
;; Die Liste fuellt vfs-vf-koerper beim Bau jedes geraden VF-Abschnitts
|
||||
;; (siehe vf-vfhoehe-segment in vf_core.lsp); hier wird sie - wie alle
|
||||
;; anderen Akkumulatoren - pro Kette zurueckgesetzt.
|
||||
(vf-vfhoehe-reset))
|
||||
|
||||
;; Alist-Zaehler erhoehen / lesen
|
||||
(defun vfl-inc-count (al key / e)
|
||||
@@ -857,10 +862,22 @@
|
||||
(set_tile "setzen" "1")
|
||||
(set_tile "winkel_90" "1")
|
||||
(set_tile "seite_links" "1")
|
||||
;; Seitenauswahl ist nur beim 90-Grad-Element wirksam: beim 30-Grad-
|
||||
;; Element folgt die Seite aus der Zufuehrungsachse, die direkt nach
|
||||
;; diesem Dialog ueber einen zweiten Punkt abgefragt wird (Nutzer-Vorgabe
|
||||
;; 2026-10-14). Sie wird darum ausgegraut - und unten auch NICHT in die
|
||||
;; Pending-Queue gelegt, sonst zoege die Punktfrage sie als vermeintlichen
|
||||
;; Punkt heraus und erschiene gar nicht.
|
||||
(action_tile "setzen"
|
||||
"(mode_tile \"winkel_90\" (if (= (get_tile \"setzen\") \"1\") 0 1))
|
||||
(mode_tile \"winkel_30\" (if (= (get_tile \"setzen\") \"1\") 0 1))
|
||||
(mode_tile \"seite_links\" (if (= (get_tile \"setzen\") \"1\") 0 1))
|
||||
(mode_tile \"seite_links\" (if (and (= (get_tile \"setzen\") \"1\") (/= (get_tile \"winkel_30\") \"1\")) 0 1))
|
||||
(mode_tile \"seite_rechts\" (if (and (= (get_tile \"setzen\") \"1\") (/= (get_tile \"winkel_30\") \"1\")) 0 1))")
|
||||
(action_tile "winkel_30"
|
||||
"(mode_tile \"seite_links\" 1)
|
||||
(mode_tile \"seite_rechts\" 1)")
|
||||
(action_tile "winkel_90"
|
||||
"(mode_tile \"seite_links\" (if (= (get_tile \"setzen\") \"1\") 0 1))
|
||||
(mode_tile \"seite_rechts\" (if (= (get_tile \"setzen\") \"1\") 0 1))")
|
||||
(action_tile "accept"
|
||||
"(setq gsetzen (get_tile \"setzen\"))
|
||||
@@ -877,7 +894,13 @@
|
||||
;; Winkel-Slot wird von vfl-in-value (AS-Winkel, ueber
|
||||
;; vf-frage-element-winkel) konsumiert - der erwartet direkt
|
||||
;; "30"/"90", NICHT den Auswahl-Index wie beim Seite-Slot.
|
||||
(vflw-pending-push-all (list "1" gwinkel gseite))
|
||||
;; Beim 30-Grad-Element wird die Seite NICHT mitgegeben: sie ist im
|
||||
;; Dialog ausgegraut und folgt aus der Zufuehrungsachse. Ein hier
|
||||
;; abgelegter Wert wuerde von der nachfolgenden Punktfrage
|
||||
;; faelschlich als Punkt konsumiert.
|
||||
(if (= gwinkel "30")
|
||||
(vflw-pending-push-all (list "1" gwinkel))
|
||||
(vflw-pending-push-all (list "1" gwinkel gseite)))
|
||||
(vflw-pending-push-all (list "2"))))
|
||||
((= ergebnis 2) (setq *vfl-wizard-abbruch-grund* "zurueck"))
|
||||
(t (setq *vfl-wizard-abbruch-grund* "abbrechen"))
|
||||
@@ -3811,6 +3834,35 @@
|
||||
;; genommen (vlax-curve-*): fuer eine LINE ist das exakt die Linie selbst, fuer
|
||||
;; eine Polylinie genau das angeklickte Segment - ohne Segment-Suche von Hand.
|
||||
;; Rueckgabe: (pa pb) oder nil.
|
||||
;; ============================================================
|
||||
;; AS-BASISLINIE: Zufuehrungsachse am Kettenanfang
|
||||
;; ============================================================
|
||||
;; Der Startpunkt einer Kette mit AS-Element ist geometrisch KEINE Position,
|
||||
;; sondern eine ACHSE: das AS sitzt an einer durchlaufenden Strecke (z.B. einer
|
||||
;; Kreiselkette) und schleust daraus aus - seine KS_EIN-Achse MUSS auf dieser
|
||||
;; Zufuehrungsachse liegen (Nutzer-Einsicht 2026-10-14, dieselbe wie beim
|
||||
;; Endpunkt: "der Punkt ist eigentlich eine Linie").
|
||||
;;
|
||||
;; Beim AS_Element_90 faellt das kaum auf, beim AS_Element_30 steht das Element
|
||||
;; sichtbar falsch: vfl-insert-as-element richtet heute das KS_AUS entlang der
|
||||
;; Kettenrichtung aus, wodurch das KS_EIN um den Blockschwenk verdreht steht.
|
||||
;;
|
||||
;; Auf welcher Seite der Zufuehrung das AS ausschleust, ergibt sich dann aus der
|
||||
;; Lage des naechsten Kettenpunkts zur Basislinie - es muss nicht gefragt werden
|
||||
;; (Nutzer-Entscheidung 2026-10-14). Im Punkt-Modus bleibt die Seitenfrage
|
||||
;; dagegen unveraendert erhalten.
|
||||
;;
|
||||
;; Reine Rechnung, in tests/test_unit.lsp getestet:
|
||||
;; Vorzeichen des 2D-Kreuzprodukts (p2-p1) x (ziel-p1).
|
||||
;; > 0 -> ziel liegt LINKS der Richtung p1->p2
|
||||
;; < 0 -> rechts
|
||||
;; Genau auf der Linie (0) gilt als "links" (willkuerlich, aber deterministisch -
|
||||
;; der Aufrufer sollte diesen Fall ohnehin nicht erzeugen).
|
||||
(defun vfl-seite-aus-lage (p1 p2 ziel / kr)
|
||||
(setq kr (vfl-kreuz2 (- (car p2) (car p1)) (- (cadr p2) (cadr p1))
|
||||
(- (car ziel) (car p1)) (- (cadr ziel) (cadr p1))))
|
||||
(if (< kr 0.0) "rechts" "links"))
|
||||
|
||||
;; Ziellinie durch ZWEI selbst gesetzte Punkte definieren.
|
||||
;;
|
||||
;; Allgemeiner als das Anklicken eines vorhandenen Objekts (Nutzer-Idee
|
||||
@@ -5063,7 +5115,10 @@
|
||||
(if sep-vor (setq pt (vfl-sep-hz pt hz)))
|
||||
;; horizontale Zwischenstrecke (0 Grad)
|
||||
(princ (ssg-textf "vfl-horizontale-zwischenstrecke" (list (rtos dL 2 2))))
|
||||
;; Hoehe dieses (horizontalen) VF-Segments erfassen - siehe vf-vfhoehe-merke.
|
||||
(vf-vfhoehe-merke pt)
|
||||
(setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" pt dL 0 hz))
|
||||
(vf-vfhoehe-schliesse pt)
|
||||
(vfl-acc-vf-seg "horizontal" 0 dL)
|
||||
;; optionaler Separator NACH (jetzt tatsaechlich bauen)
|
||||
(if sep-nach (setq pt (vfl-sep-hz pt hz)))
|
||||
@@ -5587,9 +5642,11 @@
|
||||
;; (Ausgang in vfl-vf-einheit) erledigt den einzigen wirklich
|
||||
;; noetigen Bogen.
|
||||
((and schon-flach (= typ "VF") (= w 0) lvf (> lvf 1.0))
|
||||
(vf-vfhoehe-merke (car frame))
|
||||
(setq frame (make-frame-from-dir
|
||||
(insert-inclined-scaled-block "Staustrecke_SP_1000_mm" (car frame) lvf 0 hzn)
|
||||
(hz-winkel->xu hzn 0.0)))
|
||||
(vf-vfhoehe-schliesse (car frame))
|
||||
(vfl-acc-vf-seg "horizontal" 0 lvf)
|
||||
(setq cnt (1+ cnt)))
|
||||
;; Normalfall: gewinkelter ODER horizontaler Koerper - vfs-vf-koerper
|
||||
@@ -6508,10 +6565,53 @@
|
||||
;; die noetige Restlaenge ist damit einfach die urspruengliche Distanz MINUS
|
||||
;; die tatsaechliche (gemessene) AS-Fussabdrucklaenge, keine Punkt-Projektion
|
||||
;; noetig (Ersatz fuer das fruehere vfl-projiziere-distanz auf pick-punkt).
|
||||
(defun vfl-kettenanfang-baustein (p-aktuell hz-neu deltaL as-seite as-vorhanden / frame fussabdruck)
|
||||
;; AS-Element so einfuegen, dass seine KS_EIN-ACHSE auf der Zufuehrungsachse
|
||||
;; (ein-hz) liegt - Gegenstueck zu vfl-insert-as-element, das stattdessen das
|
||||
;; KS_AUS entlang der Kettenrichtung ausrichtet.
|
||||
;;
|
||||
;; Unterschied in einer Zeile: dort wird der Blockschwenk abgezogen
|
||||
;; (ein-hz = hz - as-turn), hier NICHT - die uebergebene Richtung IST schon die
|
||||
;; des KS_EIN. Das KS_AUS zeigt danach um den Blockschwenk gedreht weiter, also
|
||||
;; beim AS_Element_30 um 30 Grad von der Zufuehrung weg: genau das reale
|
||||
;; Ausschleusen aus einer durchlaufenden Strecke (Nutzer-Einsicht 2026-10-14).
|
||||
(defun vfl-insert-as-element-auf-achse (typ startpunkt ein-hz as-seite / rad-h xu-ein)
|
||||
(setq rad-h (* (float ein-hz) (/ pi 180.0)))
|
||||
(setq xu-ein (list (cos rad-h) (sin rad-h) 0.0))
|
||||
(insert-block-mixed-to-ks
|
||||
(strcat "AS_Element_" (vfl-as-winkel) "_" as-seite)
|
||||
(make-frame-from-dir startpunkt xu-ein)
|
||||
(caddr startpunkt) nil "KS_EIN")
|
||||
)
|
||||
|
||||
(defun vfl-kettenanfang-baustein (p-aktuell hz-neu deltaL as-seite as-vorhanden
|
||||
/ frame fussabdruck ziel rad)
|
||||
(if as-vorhanden
|
||||
(progn
|
||||
(setq frame (vfl-insert-as-element "GF" p-aktuell hz-neu 0.0 as-seite))
|
||||
;; BASISLINIEN-Modus: das AS gehoert mit seinem KS_EIN auf die
|
||||
;; Zufuehrungsachse (*vfl-as-basis-hz*), nicht mit dem KS_AUS auf die
|
||||
;; Kettenrichtung. Die Seite ergibt sich aus der Lage des naechsten
|
||||
;; Kettenpunkts zur Basislinie (Nutzer-Vorgabe 2026-10-14): der liegt in
|
||||
;; Richtung hz-neu, deltaL entfernt.
|
||||
(if *vfl-as-basis-hz*
|
||||
(progn
|
||||
(setq rad (* (float hz-neu) (/ pi 180.0)))
|
||||
(setq ziel (list (+ (car p-aktuell) (* deltaL (cos rad)))
|
||||
(+ (cadr p-aktuell) (* deltaL (sin rad)))
|
||||
(caddr p-aktuell)))
|
||||
(setq as-seite (vfl-seite-aus-lage *vfl-as-basis-p1*
|
||||
(list (+ (car *vfl-as-basis-p1*)
|
||||
(cos (* *vfl-as-basis-hz* (/ pi 180.0))))
|
||||
(+ (cadr *vfl-as-basis-p1*)
|
||||
(sin (* *vfl-as-basis-hz* (/ pi 180.0))))
|
||||
0.0)
|
||||
ziel))
|
||||
;; Masse auf die jetzt bekannte Seite umstellen (Winkel steht schon).
|
||||
(vf-set-as-masse (vfl-as-winkel) as-seite)
|
||||
(princ (ssg-textf "vfl-as-seite-ermittelt" (list as-seite)))
|
||||
;; KS_EIN auf die Zufuehrungsachse legen - NICHT KS_AUS auf hz-neu.
|
||||
(setq frame (vfl-insert-as-element-auf-achse "GF" p-aktuell
|
||||
*vfl-as-basis-hz* as-seite)))
|
||||
(setq frame (vfl-insert-as-element "GF" p-aktuell hz-neu 0.0 as-seite)))
|
||||
(setq fussabdruck (vfl-planar-dist p-aktuell (car frame)))
|
||||
(setq deltaL (- deltaL fussabdruck))
|
||||
(princ (ssg-textf "vfl-info-as-eingefuegt" (list (rtos deltaL 2 1))))
|
||||
@@ -6595,6 +6695,83 @@
|
||||
(vf-set-as-masse *vfl-as-winkel* as-seite) ; Masse fuer Variante
|
||||
as-seite)
|
||||
|
||||
;; AS-Winkel abfragen und danach ENTWEDER die Seite ODER - nur beim 30-Grad-
|
||||
;; Element - eine Zufuehrungsachse (Nutzer-Vorgabe 2026-10-14: "bitte erstmal
|
||||
;; nur fuer 30 Grad").
|
||||
;;
|
||||
;; Warum erst NACH dem Winkel: die Achsenfrage gilt nur fuer AS_Element_30, der
|
||||
;; Winkel muss also schon feststehen. Der Kettenstartpunkt bleibt davon
|
||||
;; unberuehrt - er ist und bleibt der echte Sitz des AS-Elements; die Achse
|
||||
;; entsteht aus ihm plus EINEM weiteren Punkt, der nur die Richtung gibt.
|
||||
;;
|
||||
;; JOURNAL - deswegen ist die Reihenfolge so gewaehlt:
|
||||
;; 90 Grad : [STR winkel] [STR seite] <- Eintrag fuer Eintrag wie bisher
|
||||
;; 30 + Seite : [STR winkel] [STR seite] <- ebenfalls wie bisher
|
||||
;; 30 + Achse : [STR winkel] [PT p2]
|
||||
;; Die Modus-Wahl selbst wird BEWUSST NICHT journalisiert: sie ist aus der Art
|
||||
;; des naechsten Eintrags eindeutig rekonstruierbar (PT = Achse, STR = Seite).
|
||||
;; Dadurch bleiben alle aelteren Ketten ohne Sonderbehandlung editierbar.
|
||||
;;
|
||||
;; Setzt *vfl-as-basis-hz*/-p1 (nil, wenn keine Achse gewaehlt wurde).
|
||||
;; Rueckgabe: Seite. Im Achsen-Modus vorlaeufig "links" - die endgueltige Seite
|
||||
;; folgt aus der Lage des naechsten Kettenpunkts und wird in
|
||||
;; vfl-kettenanfang-baustein gesetzt (Laengsverbrauch ist seitengleich, nur das
|
||||
;; Vorzeichen des Querversatzes dreht).
|
||||
(defun vfl-frage-as-winkel-seite-oder-achse (seiten-headerkey startpunkt
|
||||
/ antwort as-seite modus p2)
|
||||
(setq *vfl-as-basis-hz* nil *vfl-as-basis-p1* nil)
|
||||
(princ (ssg-text "vf-winkel-aus-header"))
|
||||
(princ (ssg-text "vf-winkel-90"))
|
||||
(princ (ssg-text "vf-winkel-30"))
|
||||
(setq *vfl-as-winkel*
|
||||
(vfl-in-value "STR"
|
||||
(function (lambda () (vf-frage-element-winkel "vf-winkel-aus-header")))))
|
||||
;; Beim 30-Grad-Element wird die Seite NICHT gefragt (im Gruppendialog
|
||||
;; ausgegraut) - stattdessen direkt die Zufuehrungsachse ueber einen zweiten
|
||||
;; Punkt. Es gibt also keine Modus-Frage: 30 Grad = Achse, 90 Grad = Seite.
|
||||
;;
|
||||
;; AUSNAHME Replay: aeltere 30-Grad-Ketten wurden noch MIT Seitenfrage
|
||||
;; gebaut, ihr Journal hat an dieser Stelle ein "STR" statt eines "PT".
|
||||
;; Steht dort ein STR, ist es ein Altbestand und es wird wie frueher die
|
||||
;; Seite gelesen - sonst liefe die Queue aus dem Takt.
|
||||
(setq modus (if (= *vfl-as-winkel* "30") "1" "2"))
|
||||
(if (and (= modus "1") *vfl-replay-queue* (/= (vfl-replay-peek-art) "PT"))
|
||||
(setq modus "2"))
|
||||
(if (= modus "1")
|
||||
(progn
|
||||
;; Der AS-Gruppendialog legt beim 30-Grad-Element bewusst KEINE Seite in
|
||||
;; die Pending-Queue (siehe vflw-gruppe-as-impl) - die Queue ist hier
|
||||
;; also leer und der folgende vfl-in-point fragt wirklich nach dem Punkt.
|
||||
;; Zweiter Punkt gibt NUR die Richtung der Zufuehrung; der Startpunkt
|
||||
;; bleibt der Sitz des AS-Elements.
|
||||
(setq p2 (vfl-in-point startpunkt (ssg-text "vfl-prompt-as-achse-p2")))
|
||||
(if (or (null p2)
|
||||
(and (< (abs (- (car p2) (car startpunkt))) 1e-9)
|
||||
(< (abs (- (cadr p2) (cadr startpunkt))) 1e-9)))
|
||||
(progn
|
||||
;; Keine brauchbare Richtung -> auf die Seitenfrage zurueckfallen.
|
||||
;; (Der PT-Eintrag steht dann trotzdem im Journal und wird beim
|
||||
;; Replay wieder als "Achse" gelesen - deshalb hier KEIN stiller
|
||||
;; Rueckfall, sondern Abbruch.)
|
||||
(princ (ssg-text "vfl-basislinie-punkte-gleich"))
|
||||
(exit))
|
||||
(progn
|
||||
(setq *vfl-as-basis-p1* startpunkt)
|
||||
(setq *vfl-as-basis-hz* (vfl-planar-hz startpunkt p2))
|
||||
(princ (ssg-textf "vfl-basislinie-info" (list (rtos *vfl-as-basis-hz* 2 1))))
|
||||
(setq as-seite "links"))) ; vorlaeufig, s.o.
|
||||
)
|
||||
(progn
|
||||
(princ (ssg-text seiten-headerkey))
|
||||
(princ (ssg-text "gf-seite-links"))
|
||||
(princ (ssg-text "gf-seite-rechts"))
|
||||
(setq antwort (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list (ssg-text "gf-seite-links") (ssg-text "gf-seite-rechts")) 1
|
||||
seiten-headerkey))
|
||||
(setq as-seite (if (= antwort "2") "rechts" "links"))))
|
||||
(vf-set-as-masse *vfl-as-winkel* as-seite)
|
||||
as-seite)
|
||||
|
||||
;; ES-Winkel (30/90) + Seite abfragen - MARKER-FREIE Schale fuer die Modi 2/3,
|
||||
;; die das ES-Element als eigene Praeambel (Start/Ziel bereits fest) abfragen
|
||||
;; und ihr eigenes Journal-/Masse-Schema fuehren. Unterscheidet sich bewusst
|
||||
@@ -6731,6 +6908,9 @@
|
||||
(cons "L_VF_m" (vfl-join-komma *vfl-acc-lvf*))
|
||||
(cons "ANTRIEBFAHRTRICHTUNG" (vfl-join-komma *vfl-acc-richtung*))
|
||||
(cons "VF_WINKEL" (vfl-join-komma *vfl-acc-winkel*))
|
||||
;; Hoehe je Foerdereinheit (Mittelwert Umlenk-KS_EIN / Motor-KS_AUS),
|
||||
;; Meter mit 3 Nachkommastellen - Sivas 4433-4437.
|
||||
(cons "VF_HOEHE_m" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
;; Vario-Kurven (Richtungswechsel im VF-Teil), A=aussen / I=innen
|
||||
(cons "VF_Bogen_A_90" (itoa (vfl-get-count *vfl-acc-variokurve* "A_90")))
|
||||
(cons "VF_Bogen_A_60" (itoa (vfl-get-count *vfl-acc-variokurve* "A_60")))
|
||||
@@ -6995,9 +7175,12 @@
|
||||
;; werden - sonst wuerde ein WINKEL_AS-Attribut den Wert der VORHERIGEN Kette
|
||||
;; tragen, wenn diesmal kein AS gewaehlt wird.
|
||||
(setq *vfl-as-winkel* nil *vfl-es-winkel* nil)
|
||||
;; Winkel, dann Seite ODER (nur bei 30 Grad) eine Zufuehrungsachse - siehe
|
||||
;; vfl-frage-as-winkel-seite-oder-achse. Im Achsen-Modus entfaellt die
|
||||
;; Seitenfrage; die Seite folgt aus der Lage des naechsten Kettenpunkts und
|
||||
;; wird in vfl-kettenanfang-baustein bestimmt.
|
||||
(if as-vorhanden
|
||||
(setq as-seite (vfl-frage-as-winkel-seite "vfl-aus-seite-header"))
|
||||
)
|
||||
(setq as-seite (vfl-frage-as-winkel-seite-oder-achse "vfl-aus-seite-header" startpunkt)))
|
||||
;; ES-Seite wird erst am Kettenende abgefragt (siehe vfl-frage-es-seite),
|
||||
;; da das ES-Element erst dort eingefuegt wird.
|
||||
|
||||
@@ -10650,8 +10833,10 @@
|
||||
(progn (setq pt (vfl3-flach-ein pt letzt-koerper-hz)) (setq flat-p t)
|
||||
;; Fueller-A: der im Kletter-Segment durch 1/2 GF1 frei werdende Platz
|
||||
(if (and (> filler-A-len 0.1) (not filler-a-done))
|
||||
(progn (setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm"
|
||||
(progn (vf-vfhoehe-merke pt)
|
||||
(setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm"
|
||||
pt filler-A-len 0 letzt-koerper-hz))
|
||||
(vf-vfhoehe-schliesse pt)
|
||||
(vfl-acc-vf-seg "horizontal" 0 filler-A-len)
|
||||
(setq anzahl-vf (1+ anzahl-vf) filler-a-done t)))))
|
||||
(if (= i vf-ende)
|
||||
@@ -10684,7 +10869,9 @@
|
||||
"vfl-m3-warnung-fueller-ausgang-zu-kurz")
|
||||
(list (rtos fill-len 2 0) (rtos *vfk-restlaenge-min-clamp* 2 0)))))
|
||||
(setq fill-len (max *vfk-restlaenge-min-clamp* fill-len))
|
||||
(vf-vfhoehe-merke pt)
|
||||
(setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm" pt fill-len 0 seg-hz))
|
||||
(vf-vfhoehe-schliesse pt)
|
||||
(vfl-acc-vf-seg "horizontal" 0 fill-len) (setq anzahl-vf (1+ anzahl-vf))
|
||||
(setq letzt-koerper-hz seg-hz))
|
||||
;; --- Vario-Kurve (flach, direkt bei 0 Grad) ---
|
||||
@@ -10693,8 +10880,10 @@
|
||||
(progn (setq pt (vfl3-flach-ein pt letzt-koerper-hz)) (setq flat-p t)
|
||||
;; Fueller-A: der im Kletter-Segment durch 1/2 GF1 frei werdende Platz
|
||||
(if (and (> filler-A-len 0.1) (not filler-a-done))
|
||||
(progn (setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm"
|
||||
(progn (vf-vfhoehe-merke pt)
|
||||
(setq pt (insert-inclined-scaled-block "Staustrecke_SP_1000_mm"
|
||||
pt filler-A-len 0 letzt-koerper-hz))
|
||||
(vf-vfhoehe-schliesse pt)
|
||||
(vfl-acc-vf-seg "horizontal" 0 filler-A-len)
|
||||
(setq anzahl-vf (1+ anzahl-vf) filler-a-done t)))))
|
||||
(setq bwinkel (nth 3 seg) bseite (nth 4 seg) kv-variante (nth 6 seg))
|
||||
@@ -11230,6 +11419,12 @@
|
||||
(setq gemessen (vfl-kette-neigung (vfl-kette-rec-ein entry-info) (vfl-kette-rec-aus rec)))
|
||||
(setq betrag (vfl-kette-round (abs gemessen)))
|
||||
(setq richtung (if (< gemessen 0.0) "Auf" "Ab"))))
|
||||
;; Hoehe dieses Segments aus DENSELBEN Punkten, aus denen auch
|
||||
;; die Laenge kommt (Ende des Eingangsbogens bis Anfang des
|
||||
;; Ausgangsbogens) - dadurch bleiben VF_HOEHE_m und L_VF_m auch
|
||||
;; beim Rekonstruieren aus bestehenden Bloecken gleich lang.
|
||||
(vf-vfhoehe-segment (caddr (vfl-kette-rec-aus entry-info))
|
||||
(caddr (vfl-kette-rec-ein rec)))
|
||||
(vfl-acc-vf-seg richtung betrag
|
||||
(distance (vfl-kette-rec-aus entry-info) (vfl-kette-rec-ein rec)))
|
||||
(setq entry-info nil)
|
||||
@@ -11286,6 +11481,8 @@
|
||||
(cons "L_VF_m" (vfl-join-komma *vfl-acc-lvf*))
|
||||
(cons "ANTRIEBFAHRTRICHTUNG" (vfl-join-komma *vfl-acc-richtung*))
|
||||
(cons "VF_WINKEL" (vfl-join-komma *vfl-acc-winkel*))
|
||||
;; Hoehe je Foerdereinheit - siehe oben.
|
||||
(cons "VF_HOEHE_m" (vfl-join-komma *vf-acc-vfhoehe*))
|
||||
(cons "VF_Bogen_A_90" (itoa (vfl-get-count *vfl-acc-variokurve* "A_90")))
|
||||
(cons "VF_Bogen_A_60" (itoa (vfl-get-count *vfl-acc-variokurve* "A_60")))
|
||||
(cons "VF_Bogen_A_30" (itoa (vfl-get-count *vfl-acc-variokurve* "A_30")))
|
||||
|
||||
@@ -612,9 +612,15 @@
|
||||
;; beliebig aneinanderreihen (siehe doc/VarioFoerderer_Linienzug_Prinzipien.md).
|
||||
;; 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)
|
||||
bogen-name bogen-mass bogen-dx bogen-dz z-ein)
|
||||
(if (null hz) (setq hz 0.0))
|
||||
(setq hz (float hz))
|
||||
;; Hoehe DIESES VF-Segments (Attribut VF_HOEHE_m, Sivas 4433-4437):
|
||||
;; KS_EIN ist der Punkt beim Eintritt, KS_AUS der Rueckgabewert am Ende -
|
||||
;; der Mittelwert beider wird unten angehaengt. Eine Kette mit drei durch
|
||||
;; Vario-Boegen getrennten Abschnitten bekommt dadurch drei Werte, parallel
|
||||
;; zu L_VF_m und VF_WINKEL (Nutzer-Vorgabe 2026-10-21).
|
||||
(setq z-ein (caddr aktueller-punkt))
|
||||
|
||||
;; 5. 1. Vertikalbogen
|
||||
;; Sonderfall best-winkel=0 (horizontale Zwischenstrecke, siehe
|
||||
@@ -717,6 +723,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Segment-Hoehe anhaengen: Mittelwert aus KS_EIN (z-ein) und KS_AUS.
|
||||
(vf-vfhoehe-segment z-ein (caddr aktueller-punkt))
|
||||
aktueller-punkt
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user