LineSweep Algorithmus angepasst, alten Stand überschrieben. Ausgaben in Kommandozeile zu Debug-Zwecken

This commit is contained in:
2025-05-12 13:50:51 +02:00
parent ae86dbcafa
commit 3a7b3aeece
+64 -51
View File
@@ -1,75 +1,88 @@
import json
from shapely.geometry import LineString, Point
from shapely.ops import nearest_points
# === Konfiguration ===
tol = 200
tol_step = 10
"""Code läuft Racks nacheinander entlang. Über vorgegebene toleranz wird bounding Box erzeugt
und infrage kommende Punkte aufgezeichnet. Bei exaktem Schnittpunkt wird zu überprüfendes Rack
und Schnittpunkt mit Punkt in Verbindungen aufgenommen. Bei nicht exaktem Schnittpunkt wird
wachsender Kreis um Punkt gezeichnet bis Rack geschnitten wird. Dieser Schnittpunkt dann in
Verbindungen aufgenommen.
"""
racks = [
((0, 0), (5, 0)), # Horizontal
((0, 0), (0, 5)), # Vertikal (schneidet exakt)
((0.25, 2), (5, 2)), # Parallel mit 0.25 Abstand zur Vertikalen
((0.25, 4), (4, 3)), # Diagonal
((5.10, -0.25), (5.1, 3)) # Parallel sehr nah an erstem Rack
]
# === Lade JSON-Daten ===
with open("C:/10-Develop/kabellaengen/work/easy_positions.json", "r") as f:
data = json.load(f)
tol = 0.5
tol_step = 0.05
racks_json = data["racks"] #Suchen nach Racks in gesamter Json-Übergabe
rack_lines = [LineString([start, end]) for start, end in racks]
rack_endpoints = [(i, pt) for i, rack in enumerate(racks) for pt in rack]
# === 1. Racks in Segmente zerlegen ===
''' Hier werden Racks, die aus "echter" Polylinie bestehen (mehrere Nodes, z.B. Rack 2 in easy.dxf) in einzelne Segmente zerlegt (Node1 -> Node2, Node2 -> Node3)'''
rack_segments = []
for rack_id, nodes in racks_json.items():
# Sortiere Node_1, Node_2, ...
sorted_keys = sorted(nodes.keys(), key=lambda k: int(k.split("_")[1]))
coords = [tuple(nodes[k]) for k in sorted_keys]
for i in range(len(coords) - 1):
p1, p2 = coords[i], coords[i+1]
line = LineString([p1, p2])
rack_segments.append((rack_id, i, line))
# === 2. Alle Endpunkte sammeln ===
''' Alle Endpunkte aller Racks als Point gespeichert, um shapely funktionen verwenden zu können'''
segment_endpoints = []
for rack_id, idx, line in rack_segments:
for pt in [line.coords[0], line.coords[1]]:
segment_endpoints.append((rack_id, idx, Point(pt)))
# === 3. Verbindungen suchen ===
verbindungen = []
# Überprüfe jedes Rack
for i, rack_line in enumerate(rack_lines):
print(f"\n=== Prüfe Rack {i}: {rack_line}")
# === A: Echte Schnittpunkte zwischen Linien finden ===
''' Alle Segmente mit allen überprüfen, um echte SP zu finden'''
for i, (rack_id1, idx1, line1) in enumerate(rack_segments):
print(f"\n=== Prüfe {rack_id1}_{idx1} auf echte Schnittpunkte")
for j, (rack_id2, idx2, line2) in enumerate(rack_segments):
if i >= j:
continue # keine Duplikate / sich selbst
for j, pt_coords in rack_endpoints:
if i == j:
continue # Eigenpunkte ignorieren
if line1.intersects(line2):
inter = line1.intersection(line2)
if inter.geom_type == "Point":
print(f"✅ Exakter Schnittpunkt {inter} zwischen {rack_id1}_{idx1} und {rack_id2}_{idx2}")
verbindungen.append((rack_id1, rack_id2, inter))
pt = Point(pt_coords)
# Prüfe auf exakten Schnittpunkt
if rack_line.intersects(pt):
intersection = rack_line.intersection(pt)
print(f" ✅ Echter Schnittpunkt mit Endpunkt von Rack {j}: {intersection}")
verbindungen.append((i,j, intersection))
continue #diesen Punkt überspringen
# === B: Näherungsweise Verbindung durch Toleranz-Kreise ===
''' Entlanglaufen der Racks und Scan nach Endpunkten im Toleranzbereich'''
for rack_id, idx, line in rack_segments:
print(f"\n=== Prüfe {rack_id}_{idx1} auf Punkte im Toleranzbereich")
for other_rack_id, other_idx, pt in segment_endpoints:
if rack_id == other_rack_id:
continue # ignoriere eigene Endpunkte
#alle Endpunkte prüfen, die NICHT exakt auf der Linie liegen
for j, pt_coords in rack_endpoints:
if i == j:
continue # Eigenpunkte ignorieren
# Exakte Schnittpunkte ignorieren
if line.intersects(pt):
continue
pt = Point(pt_coords)
# Prüfe nur, wenn der Punkt **nicht** genau auf der Linie liegt
if rack_line.intersects(pt):
continue # Exakte Schnittpunkte nicht erneut behandeln
dist = rack_line.distance(pt)
#überprüfen, ob der Punkt im Toleranzbereich ist
dist = line.distance(pt)
if dist < tol:
print(f" 🔍 Punkt {pt} liegt {dist:.3f} von Linie {i} entfernt")
print(f"🔍 Punkt {pt} liegt {dist:.2f} von Linie {rack_id}_{idx} entfernt")
radius = tol_step
while radius <= tol:
circle = pt.buffer(radius) # Kreis wächst mit dem Toleranzradius
if circle.intersects(rack_line): # Wenn der Kreis die Linie schneidet
contact = circle.intersection(rack_line)
circle = pt.buffer(radius)
if circle.intersects(line):
contact = circle.intersection(line)
if contact.geom_type == "Point":
nearest = contact
else:
nearest = nearest_points(pt, contact)[1] # Erster Kontaktpunkt von rack_line
print(f" 🟡 Berührpunkt bei Radius {radius:.2f}: {nearest}")
verbindungen.append((i,j,nearest))
nearest = nearest_points(pt, contact)[1]
print(f" 🟡 Kreisberührung bei {nearest} mit {rack_id}_{idx}")
verbindungen.append((rack_id, other_rack_id, nearest))
break
radius += tol_step
# === Ausgabe-Verbindungen ===
print("\n=== Gefundene Verbindungen ===")
for v in verbindungen:
print(v)