[CHANGE] Omniflo-Nachbarschaft: STRtree-Broad-Phase + KOS-Verfeinerung (10mm); Gerade-K1/K2 im CSV-Export

Die Omniflo-Nachbarschaftserkennung (export_neighbors.py, nur EXPORTCSV) wird
zweistufig:
- Broad-Phase ueber shapely-STRtree auf den Bounding-Boxen (Fallback: das
  bisherige Raster, falls shapely fehlt).
- Narrow-Phase (KOS-Verfeinerung): zwei moegliche Nachbarn gelten nur dann als
  benachbart, wenn ein Anschluss-Koordinatensystem K1-K4 des einen naeher als
  omniflo_ks_toleranz_mm (neu, Default 10mm) an einem K-Punkt des anderen
  liegt. Das verwirft bloss ueberlappende BBoxen ohne echten Anschluss.
  Elemente ohne K1-K4 fallen auf reine BBox-Ueberschneidung zurueck.

Geraden fuehren keine echten K-Bloecke in der Zeichnung; ihre K1 (Anfang) /
K2 (Ende) werden beim Export aus Einfuegepunkt + Laenge + Rotation
synthetisiert (csv:gerade-k-kos-strings in export.lsp) und stehen damit in den
CSV-Spalten K1/K2 - wie echte KOS - und nehmen an der Kollisionspruefung teil.

Verifiziert an results/test-omnicollision: gerichtete Nachbarschaften 20 -> 14.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:56:10 +02:00
parent bd79e3d1b6
commit 9c8f84799c
5 changed files with 282 additions and 47 deletions
+40
View File
@@ -350,6 +350,37 @@
(if found (cdr found) "")
)
;; --- K1 (Anfang) / K2 (Ende) einer Omniflo-Gerade SYNTHETISIEREN ---
;; ename = Entity-Name des platzierten Gerade-INSERT.
;; pt/rot-rad = Welt-Einfuegepunkt (= Anfang) und -Rotation (radiant) des
;; Blocks (siehe csv:block-to-json).
;; Geraden fuehren - anders als Boegen/Weichen - KEINE echten K-Bloecke in der
;; Zeichnung. Fuer den Export werden ihre Anschluss-Koordinatensysteme aus der
;; Geometrie berechnet, als laegen dort echte KOS: K1 am Einfuegepunkt (Anfang
;; der lokalen Linie 0,0), K2 am Ende (laenge,0), ueber die Block-Rotation in
;; Weltkoordinaten gedreht. Laenge aus dem LAENGE- bzw. A-Attribut. Damit
;; koennen Geraden in der Python-Nachbarschaftserkennung (export_neighbors.py)
;; genauso ueber ihre KOS gegen andere Geraden/Boegen/Weichen geprueft werden.
;; Rueckgabe wie csv:get-k-kos-strings: (("K1" . str) ("K2" . str)) oder nil.
(defun csv:gerade-k-kos-strings (ename pt rot-rad / laenge-str laenge z end-pt)
(setq laenge-str (cond ((csv:get-attrib ename "LAENGE"))
((csv:get-attrib ename "A"))
(t nil)))
(if (and laenge-str (> (strlen laenge-str) 0))
(progn
(setq laenge (atof laenge-str))
(setq z (if (caddr pt) (caddr pt) 0.0))
(setq end-pt (list (+ (car pt) (* laenge (cos rot-rad)))
(+ (cadr pt) (* laenge (sin rot-rad)))
z))
(list
(cons "K1" (csv:trans-encode (car pt) (cadr pt) z))
(cons "K2" (csv:trans-encode (car end-pt) (cadr end-pt) (caddr end-pt))))
)
nil
)
)
;; --- Mindesthoehe der Bounding-Box (Z-Ausdehnung), aus cfg/export.cfg ---
;; [Boundingbox] bb_minimum_height_mm, Default 1 (mm) falls nicht gesetzt.
@@ -446,6 +477,15 @@
(car pt) (cadr pt) (if (caddr pt) (caddr pt) 0.0)
(nth 0 insert-quat) (nth 1 insert-quat) (nth 2 insert-quat) (nth 3 insert-quat)))
(setq k-list (csv:get-k-kos-strings ename pt rotation))
;; Omniflo-Geraden fuehren keine echten K-Bloecke - K1/K2 aus der Geometrie
;; (Anfang/Ende ueber Laenge + Rotation) synthetisieren, damit sie im Export
;; wie echte Anschluss-Koordinatensysteme erscheinen und in der Nachbar-
;; schaftserkennung (export_neighbors.py) mitverwendet werden koennen.
(if (and (null k-list)
(wcmatch (strcase blk-name)
(export:pattern "pattern_gerade" "AP110*,AP_110*")))
(setq k-list (csv:gerade-k-kos-strings ename pt rotation))
)
(setq bbox-json "")
(if include-bbox
(progn