feat: AS-Zufuehrungsachse fuer beide Winkel + GF-Option "Parallel zum Kreisel"

Die AS-Praeambel in Modus 1 fragt jetzt Winkel, Seite UND eine optionale
Zufuehrungsachse (2. Punkt) - im Assistenten alles in einem Fenster
(vflw_as_achse). Beide Angaben zusammen legen das AS vollstaendig fest: der
2. Punkt gibt die KS_EIN-Achse (Zufuehrung/Fahrtrichtung), links/rechts die
AS-Variante und damit die KS_AUS-Richtung der Kette. Bisher galt die Achse
nur beim 30-Grad-Element und ERSETZTE dort die Seitenfrage.

Darauf setzt die neue 5. Option der gf-laenge-modus-Frage auf, intern
"parallel" (vfl-gf-parallel-kreisel): AS -> GF-Stueck -> GF-Bogen aus EINEM
Abstandswert, gemessen senkrecht zur Zufuehrungsachse von AS-KS_EIN bis
Bogen-KS_AUS. Kein Separator dazwischen, damit der Abstand exakt getroffen
wird; die Kettenende-Frage stellt der Zweig selbst NACH dem Bau. Waehlbar
nur am Kettenanfang mit AS UND Achse.

Der Bogen ist nicht verdrahtet: gewaehlt wird der, der den gemessenen
Grundriss-Schwenk des AS-Blocks aufhebt (vf-element-plan-turn) - mit den
vorhandenen Bausteinen AS 30 -> 30-Grad-Bogen, AS 90 -> 90-Grad-Bogen,
immer zur Gegenseite. Querversatz von AS und Bogen wird gemessen statt
gerechnet; die Bogen-Probe laeuft dabei auf dem IDEALISIERTEN 3-Grad-Rahmen,
auf dem der echte Bogen spaeter sitzt (auf dem AS-Rahmen gemessen lag der
Abstand im BricsCAD-Test um 0.5 mm daneben).

Journal: [STR winkel][STR seite][PT p2 | NIL]. Welche Fragen gestellt wurden,
wird nicht journalisiert, sondern beim Replay an der Eintragsart erkannt -
alte Ketten bleiben ohne Sonderbehandlung editierbar. Die Journal-Werkzeuge
(vf_linienzug_grammatik.py, vf_spec_export.py, vf_journal_export.py,
vf_spec.lsp, test_hm_recformat.lsp) kennen das optionale Achsen-Token.

Tests: 11 neue Unit-Tests fuer die reinen Kerne vfl-par-bogen-waehlen und
vfl-par-gf-laenge (tu-tests-vfl-parallel), TEST_UNIT 701/701 gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 11:04:16 +02:00
parent cccd362bba
commit 1cc163dc11
12 changed files with 815 additions and 150 deletions
+55 -1
View File
@@ -399,6 +399,59 @@
)
;; ------------------------------------------------------------
;; TESTS: vf_linienzug.lsp - "Parallel zum Kreisel" (Rechenkerne)
;; ------------------------------------------------------------
;; Die Bau-Funktion vfl-gf-parallel-kreisel braucht eine Zeichnung (sie misst
;; AS und Bogen an echten Bloecken); ihre beiden Rechenkerne sind davon frei
;; und stehen deshalb hier:
;; vfl-par-bogen-waehlen - welcher Bogen hebt den AS-Schwenk auf?
;; vfl-par-gf-laenge - wie lang wird das GF-Stueck dazwischen?
;; Die Plan-Turn-Werte unten sind die Vorzeichen-Konvention aus
;; vf-element-plan-turn (KS_EIN -> KS_AUS in der XY-Ebene, links positiv).
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l)
(princ "\n[vf_linienzug Parallel zum Kreisel]")
;; --- Bogenwahl: der Bogen muss den AS-Schwenk GENAU aufheben ---
;; Rechts-Boegen schwenken negativ, Links-Boegen positiv.
(setq _b30 '(30 . -30.0) _b60 '(60 . -60.0) _b90 '(90 . -90.0))
(setq _kand (list _b30 _b60 _b90))
;; AS links 30 Grad (Schwenk +30) -> 30-Grad-Bogen nach rechts
(tu-eq "vfl-par-bogen/as30-rechts" 30 (vfl-par-bogen-waehlen 30.0 _kand 2.0))
;; AS links 90 Grad (Schwenk +90) -> 90-Grad-Bogen nach rechts
(tu-eq "vfl-par-bogen/as90-rechts" 90 (vfl-par-bogen-waehlen 90.0 _kand 2.0))
;; Generisch: auch ein 60-Grad-Schwenk findet seinen Bogen - die Zuordnung
;; folgt den gemessenen Bloecken, nicht einer gepflegten Tabelle.
(tu-eq "vfl-par-bogen/as60-rechts" 60 (vfl-par-bogen-waehlen 60.0 _kand 2.0))
;; kleine Messabweichung bleibt in der Toleranz
(tu-eq "vfl-par-bogen/toleranz-ok" 30 (vfl-par-bogen-waehlen 31.2 _kand 2.0))
;; ausserhalb der Toleranz: lieber nil als ein schiefer Bogen
(tu-nil "vfl-par-bogen/zu-weit-weg" (vfl-par-bogen-waehlen 45.0 _kand 2.0))
(tu-nil "vfl-par-bogen/leere-liste" (vfl-par-bogen-waehlen 30.0 '() 2.0))
;; Gegenseite: Links-Boegen heben einen negativen AS-Schwenk auf
(setq _kand (list '(30 . 30.0) '(60 . 60.0) '(90 . 90.0)))
(tu-eq "vfl-par-bogen/as-rechts30-links" 30 (vfl-par-bogen-waehlen -30.0 _kand 2.0))
;; --- GF-Laenge: abstand = perp-as + L*k + perp-bogen ---
;; Glatter Fall: k = 1 (AS schwenkt 90 Grad aus der Achse), feste Anteile
;; zusammen 500 -> fuer 2000 mm Abstand bleiben 1500 mm GF.
(tu-eqf "vfl-par-laenge/k1" 1500.0 (vfl-par-gf-laenge 2000.0 200.0 300.0 1.0))
;; Gegenseite: k negativ -> der Abstand zaehlt auf der anderen Seite, der
;; Betrag der Eingabe bleibt derselbe (Seite kommt aus der AS-Variante).
(tu-eqf "vfl-par-laenge/k-negativ" 1500.0
(vfl-par-gf-laenge 2000.0 -200.0 -300.0 -1.0))
;; Schraege Ausschleusung: k = sin(60 Grad)
(setq _l (vfl-par-gf-laenge 2000.0 0.0 0.0 (sin (/ (* 60.0 pi) 180.0))))
(tu-eqf "vfl-par-laenge/k-sin60" (/ 2000.0 (sin (/ (* 60.0 pi) 180.0))) _l)
;; Abstand kleiner als der feste Anteil -> negative Laenge (der Aufrufer
;; meldet das als "Abstand zu klein", die Rechnung selbst raet nicht).
(tu-true "vfl-par-laenge/zu-klein-negativ"
(< (vfl-par-gf-laenge 100.0 200.0 300.0 1.0) 0.0))
;; AS schwenkt gar nicht aus der Achse -> keine Loesung
(tu-nil "vfl-par-laenge/kein-versatz" (vfl-par-gf-laenge 2000.0 0.0 0.0 0.0))
)
;; ------------------------------------------------------------
;; TESTS: vf_linienzug.lsp - Laenge aus einer Ziellinie (X/Y)
;; ------------------------------------------------------------
@@ -2365,7 +2418,8 @@
(princ "\n================================================================")
(foreach fn '("tu-tests-core" "tu-tests-lang" "tu-tests-id" "tu-tests-vfcore"
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-ziellinie"
"tu-tests-etage" "tu-tests-vfl-es" "tu-tests-vfl-parallel"
"tu-tests-vfl-ziellinie"
"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"