From 5ae1fc308c397f2ab726b2b8e799ac265c0c6db3 Mon Sep 17 00:00:00 2001 From: Simon Hensch Date: Fri, 9 Oct 2026 08:12:04 +0200 Subject: [PATCH] =?UTF-8?q?[CHANGE]=20Eckverbindungen=20werden=20nun=20als?= =?UTF-8?q?=20T-Verbindung=20gez=C3=A4hlt=20und=20ausgewiesen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- lisp/README_LISP.md | 27 ++++++---------- lisp/verbindungszaehler.lsp | 45 ++++++++++++--------------- python/README_PYTHON.md | 2 ++ python/src/lib/dxf_analyzer.py | 56 ++++++++++++++++++++++------------ 5 files changed, 69 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 6567e32..2095fe4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Verbindungspunkte werden klassifiziert in: - Kreuzungen - T-Verbindungen -- Eckverbindungen + +Eckverbindungen (zwei aufeinander stoßende Endpunkte) werden geometrisch weiterhin erkannt, im Ergebnis aber als T-Verbindungen ausgewiesen — es wird derselbe Gerüstverbinder verbaut. ## Implementierungen diff --git a/lisp/README_LISP.md b/lisp/README_LISP.md index 1029dbe..7f295ca 100644 --- a/lisp/README_LISP.md +++ b/lisp/README_LISP.md @@ -63,15 +63,16 @@ Linien gefunden: 42 ## Verbindungstypen -Das Skript unterscheidet drei Typen: +Das Skript unterscheidet im Ergebnis zwei Typen: | Typ | Beschreibung | Erkennungslogik | Layer | Farbe | |---|---|---|---|---| | **Kreuzung** | Zwei Linien kreuzen sich, Schnittpunkt liegt im Inneren beider Linien | Nur echter geometrischer Schnitt, toleranzunabhängig | `D-KREUZUNG` | Rot (1) | -| **T-Verbindung** | Ein Endpunkt liegt auf dem Inneren der anderen Linie | Toleranzbasiert | `D-T_VERBINDUNG` | Grün (3) | -| **Eckverbindung** | Zwei Endpunkte berühren sich | Toleranzbasiert | `D-ECKVERBINDUNG` | Gelb (5) | +| **T-Verbindung** | Ein Endpunkt liegt auf dem Inneren der anderen Linie **oder** zwei Endpunkte berühren sich (Eckverbindung) | Toleranzbasiert | `D-T_VERBINDUNG` | Grün (3) | -> **Wichtig:** Kreuzungen werden ausschließlich über echten geometrischen Schnitt erkannt — niemals über Toleranz. T-Verbindungen und Eckverbindungen werden niemals als Kreuzung klassifiziert, auch wenn sich die verlängerten Linien schneiden würden. +> **Wichtig:** Kreuzungen werden ausschließlich über echten geometrischen Schnitt erkannt — niemals über Toleranz. Endpunkt-Verbindungen werden niemals als Kreuzung klassifiziert, auch wenn sich die verlängerten Linien schneiden würden. +> +> **Hinweis:** Intern trennt `classify-intersection` weiterhin zwischen T-Verbindung (ein Endpunkt) und Eckverbindung (zwei Endpunkte). Für die Ausgabe fasst `display-type` beide zur T-Verbindung zusammen, da derselbe Gerüstverbinder verbaut wird. --- @@ -106,20 +107,10 @@ Nach der Auswertung wird automatisch eine Textdatei im Verzeichnis der Zeichnung VERBINDUNGSTYPEN ------------------------------------------------ - Kreuzungen : 3 - T-Verbindungen : 8 - Eckverbindungen : 12 + Kreuzungen : 3 + T-Verbindungen : 20 ------------------------------------------------- - SUMMEN ------------------------------------------------- - - Kreuzungen : 3 - Kontaktpunkte (T + Eck) : 20 - davon T-Verbindungen : 8 - davon Eckverbindungen : 12 - - GESAMT : 23 + GESAMT : 23 ================================================ ``` @@ -128,7 +119,7 @@ Nach der Auswertung wird automatisch eine Textdatei im Verzeichnis der Zeichnung ## Toleranz — Hinweise -Die Toleranz wirkt **ausschließlich** auf T-Verbindungen und Eckverbindungen: +Die Toleranz wirkt **ausschließlich** auf T-Verbindungen (also auf alle Endpunkt-Verbindungen), nie auf Kreuzungen: - Zu **klein**: Echte Verbindungen werden nicht erkannt (z.B. bei minimal versetzten Endpunkten durch Zeichenungenauigkeit) - Zu **groß**: Linien die sich nicht berühren werden fälschlich als verbunden gezählt diff --git a/lisp/verbindungszaehler.lsp b/lisp/verbindungszaehler.lsp index fabc5fd..5a94de6 100644 --- a/lisp/verbindungszaehler.lsp +++ b/lisp/verbindungszaehler.lsp @@ -277,6 +277,13 @@ ) ) +;; Bildet den intern klassifizierten Typ auf den Anzeigetyp ab. +;; Eckverbindungen werden als T-Verbindungen ausgegeben, da derselbe +;; Gerüstverbinder verbaut wird. +(defun display-type (typ) + (if (= typ "Eckverbindung") "T-Verbindung" typ) +) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DRAW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -339,12 +346,10 @@ ;; TEXTDATEI-EXPORT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun write-report (all-pts filepath layers / f n-kr n-tv n-ek n-kontakt n-gesamt) - (setq n-kr (count-by-type all-pts "Kreuzung")) - (setq n-tv (count-by-type all-pts "T-Verbindung")) - (setq n-ek (count-by-type all-pts "Eckverbindung")) - (setq n-kontakt (+ n-tv n-ek)) - (setq n-gesamt (length all-pts)) +(defun write-report (all-pts filepath layers / f n-kr n-tv n-gesamt) + (setq n-kr (count-by-type all-pts "Kreuzung")) + (setq n-tv (count-by-type all-pts "T-Verbindung")) + (setq n-gesamt (length all-pts)) (setq f (open filepath "w")) (if (not f) @@ -372,20 +377,10 @@ (write-line " VERBINDUNGSTYPEN" f) (write-line "------------------------------------------------" f) (write-line "" f) - (write-line (strcat " Kreuzungen : " (itoa n-kr)) f) - (write-line (strcat " T-Verbindungen : " (itoa n-tv)) f) - (write-line (strcat " Eckverbindungen : " (itoa n-ek)) f) + (write-line (strcat " Kreuzungen : " (itoa n-kr)) f) + (write-line (strcat " T-Verbindungen : " (itoa n-tv)) f) (write-line "" f) - (write-line "------------------------------------------------" f) - (write-line " SUMMEN" f) - (write-line "------------------------------------------------" f) - (write-line "" f) - (write-line (strcat " Kreuzungen : " (itoa n-kr)) f) - (write-line (strcat " Kontaktpunkte (T + Eck) : " (itoa n-kontakt)) f) - (write-line (strcat " davon T-Verbindungen : " (itoa n-tv)) f) - (write-line (strcat " davon Eckverbindungen : " (itoa n-ek)) f) - (write-line "" f) - (write-line (strcat " GESAMT : " (itoa n-gesamt)) f) + (write-line (strcat " GESAMT : " (itoa n-gesamt)) f) (write-line "" f) (write-line "================================================" f) (close f) @@ -514,7 +509,6 @@ (ensure-layer "D-KREUZUNG" 1) (ensure-layer "D-T_VERBINDUNG" 3) - (ensure-layer "D-ECKVERBINDUNG" 5) (prompt (strcat "\nLinien gefunden: " (itoa (length lines)))) @@ -536,11 +530,11 @@ (setq typ (cdr result)) ;; Typ — direkt aus find-intersection (if (not (point-exists pt all-pts tol)) (progn + (setq typ (display-type typ)) (setq all-pts (cons (list (car pt) (cadr pt) typ) all-pts)) (cond - ((= typ "Kreuzung") (create-circle pt radius "D-KREUZUNG")) - ((= typ "T-Verbindung") (create-circle pt radius "D-T_VERBINDUNG")) - ((= typ "Eckverbindung") (create-circle pt radius "D-ECKVERBINDUNG")) + ((= typ "Kreuzung") (create-circle pt radius "D-KREUZUNG")) + ((= typ "T-Verbindung") (create-circle pt radius "D-T_VERBINDUNG")) ) ) ) @@ -554,10 +548,9 @@ ) (prompt "\n\n===== ERGEBNIS =====") - (prompt (strcat "\nKreuzungen: " (itoa (count-by-type all-pts "Kreuzung")))) + (prompt (strcat "\nKreuzungen: " (itoa (count-by-type all-pts "Kreuzung")))) (prompt (strcat "\nT-Verbindungen: " (itoa (count-by-type all-pts "T-Verbindung")))) - (prompt (strcat "\nEckverbindungen: " (itoa (count-by-type all-pts "Eckverbindung")))) - (prompt (strcat "\nGESAMT: " (itoa (length all-pts)))) + (prompt (strcat "\nGESAMT: " (itoa (length all-pts)))) ;; ── Report schreiben ────────────────────────────────────── (setq dwg-name diff --git a/python/README_PYTHON.md b/python/README_PYTHON.md index 0e5e325..93b6afb 100644 --- a/python/README_PYTHON.md +++ b/python/README_PYTHON.md @@ -90,6 +90,8 @@ Das Tool erzeugt für jede analysierte DXF-Datei zwei Dateien im `output/`-Verze 2. **[Dateiname]_analyse_[Datum]_[Zeit].txt** Textbericht mit Details zu den gefundenen Verbindungen (Koordinaten, Anzahl, etc.) +Der Bericht unterscheidet zwei Kategorien: **Kreuzungen** und **T-Verbindungen**. Eckverbindungen (zwei aufeinander stoßende Endpunkte) werden intern weiterhin erkannt, aber als T-Verbindungen ausgewiesen — es wird derselbe Gerüstverbinder verbaut. Entsprechend werden nur die Layer `D-KREUZUNG` (rot) und `D-T_VERBINDUNG` (grün) in der markierten DXF angelegt. + **Beispiel:** ```text diff --git a/python/src/lib/dxf_analyzer.py b/python/src/lib/dxf_analyzer.py index 74183ac..b88de85 100644 --- a/python/src/lib/dxf_analyzer.py +++ b/python/src/lib/dxf_analyzer.py @@ -12,6 +12,14 @@ from math import sin, cos, pi from datetime import datetime class IntersectionAnalyzer: + # Abbildung der intern klassifizierten Typen auf die Anzeigekategorien. + # Eckverbindungen werden als T-Verbindungen ausgegeben. + DISPLAY_TYPE = { + 'Kreuzung': 'Kreuzung', + 'T-Verbindung': 'T-Verbindung', + 'Eckverbindung': 'T-Verbindung' + } + def __init__(self, dxf_path, layer_names, tolerance=0.1, mark_radius=50): """ Initialisiert den Analysator @@ -247,23 +255,32 @@ class IntersectionAnalyzer: total = sum(len(v) for v in self.intersections.values()) print(f"\n=== ZUSAMMENFASSUNG ===") print(f"Gefundene Schnittpunkte: {total}") - for itype, points in self.intersections.items(): + for itype, points in self.display_intersections().items(): print(f" {itype}: {len(points)}") - + + def display_intersections(self): + """ + Fasst die intern klassifizierten Kategorien zu den Anzeigekategorien + zusammen. Eckverbindungen werden als T-Verbindungen ausgegeben, da + derselbe Gerüstverbinder verbaut wird. + """ + merged = {'Kreuzung': [], 'T-Verbindung': []} + for itype, points in self.intersections.items(): + merged[self.DISPLAY_TYPE[itype]].extend(points) + return merged + def create_marking_layers(self): """Erstellt Layer für die Markierungen""" layer_names = { 'Kreuzung': 'D-KREUZUNG', - 'T-Verbindung': 'D-T_VERBINDUNG', - 'Eckverbindung': 'D-ECKVERBINDUNG' + 'T-Verbindung': 'D-T_VERBINDUNG' } - + colors = { 'Kreuzung': 1, # Rot - 'T-Verbindung': 3, # Grün - 'Eckverbindung': 5 # Blau + 'T-Verbindung': 3 # Grün } - + for itype, layer_name in layer_names.items(): if layer_name not in self.doc.layers: self.doc.layers.add( @@ -280,9 +297,9 @@ class IntersectionAnalyzer: msp = self.doc.modelspace() radius = self.mark_radius - for itype, points in self.intersections.items(): + for itype, points in self.display_intersections().items(): layer_name = layer_names[itype] - + for point in points: msp.add_circle( center=(point.x, point.y), @@ -326,21 +343,22 @@ class IntersectionAnalyzer: f.write("SCHNITTPUNKT-STATISTIK\n") f.write("-" * 60 + "\n\n") - total = sum(len(v) for v in self.intersections.values()) - - for itype in ['Kreuzung', 'T-Verbindung', 'Eckverbindung']: - count = len(self.intersections[itype]) + display = self.display_intersections() + total = sum(len(v) for v in display.values()) + + for itype in ['Kreuzung', 'T-Verbindung']: + count = len(display[itype]) percentage = (count / total * 100) if total > 0 else 0 f.write(f"{itype:20s}: {count:5d} ({percentage:5.1f}%)\n") - + f.write(f"\n{'GESAMT':20s}: {total:5d}\n\n") - + f.write("-" * 60 + "\n") f.write("DETAILS DER SCHNITTPUNKTE\n") f.write("-" * 60 + "\n\n") - - for itype in ['Kreuzung', 'T-Verbindung', 'Eckverbindung']: - points = self.intersections[itype] + + for itype in ['Kreuzung', 'T-Verbindung']: + points = display[itype] f.write(f"\n{itype} ({len(points)} Stück):\n") f.write("-" * 40 + "\n")