LineSweep Algorithmus angepasst, alten Stand überschrieben. Ausgaben in Kommandozeile zu Debug-Zwecken
This commit is contained in:
+64
-51
@@ -1,75 +1,88 @@
|
|||||||
|
import json
|
||||||
from shapely.geometry import LineString, Point
|
from shapely.geometry import LineString, Point
|
||||||
from shapely.ops import nearest_points
|
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
|
# === Lade JSON-Daten ===
|
||||||
und infrage kommende Punkte aufgezeichnet. Bei exaktem Schnittpunkt wird zu überprüfendes Rack
|
with open("C:/10-Develop/kabellaengen/work/easy_positions.json", "r") as f:
|
||||||
und Schnittpunkt mit Punkt in Verbindungen aufgenommen. Bei nicht exaktem Schnittpunkt wird
|
data = json.load(f)
|
||||||
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
|
|
||||||
]
|
|
||||||
|
|
||||||
tol = 0.5
|
racks_json = data["racks"] #Suchen nach Racks in gesamter Json-Übergabe
|
||||||
tol_step = 0.05
|
|
||||||
|
|
||||||
rack_lines = [LineString([start, end]) for start, end in racks]
|
# === 1. Racks in Segmente zerlegen ===
|
||||||
rack_endpoints = [(i, pt) for i, rack in enumerate(racks) for pt in rack]
|
''' 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 = []
|
verbindungen = []
|
||||||
|
|
||||||
# Überprüfe jedes Rack
|
# === A: Echte Schnittpunkte zwischen Linien finden ===
|
||||||
for i, rack_line in enumerate(rack_lines):
|
''' Alle Segmente mit allen überprüfen, um echte SP zu finden'''
|
||||||
print(f"\n=== Prüfe Rack {i}: {rack_line}")
|
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 line1.intersects(line2):
|
||||||
if i == j:
|
inter = line1.intersection(line2)
|
||||||
continue # Eigenpunkte ignorieren
|
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
|
# === B: Näherungsweise Verbindung durch Toleranz-Kreise ===
|
||||||
if rack_line.intersects(pt):
|
''' Entlanglaufen der Racks und Scan nach Endpunkten im Toleranzbereich'''
|
||||||
intersection = rack_line.intersection(pt)
|
for rack_id, idx, line in rack_segments:
|
||||||
print(f" ✅ Echter Schnittpunkt mit Endpunkt von Rack {j}: {intersection}")
|
print(f"\n=== Prüfe {rack_id}_{idx1} auf Punkte im Toleranzbereich")
|
||||||
verbindungen.append((i,j, intersection))
|
for other_rack_id, other_idx, pt in segment_endpoints:
|
||||||
continue #diesen Punkt überspringen
|
if rack_id == other_rack_id:
|
||||||
|
continue # ignoriere eigene Endpunkte
|
||||||
|
|
||||||
#alle Endpunkte prüfen, die NICHT exakt auf der Linie liegen
|
# Exakte Schnittpunkte ignorieren
|
||||||
for j, pt_coords in rack_endpoints:
|
if line.intersects(pt):
|
||||||
if i == j:
|
continue
|
||||||
continue # Eigenpunkte ignorieren
|
|
||||||
|
|
||||||
pt = Point(pt_coords)
|
dist = line.distance(pt)
|
||||||
|
|
||||||
# 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
|
|
||||||
if dist < tol:
|
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
|
radius = tol_step
|
||||||
while radius <= tol:
|
while radius <= tol:
|
||||||
circle = pt.buffer(radius) # Kreis wächst mit dem Toleranzradius
|
circle = pt.buffer(radius)
|
||||||
if circle.intersects(rack_line): # Wenn der Kreis die Linie schneidet
|
if circle.intersects(line):
|
||||||
contact = circle.intersection(rack_line)
|
contact = circle.intersection(line)
|
||||||
if contact.geom_type == "Point":
|
if contact.geom_type == "Point":
|
||||||
nearest = contact
|
nearest = contact
|
||||||
else:
|
else:
|
||||||
nearest = nearest_points(pt, contact)[1] # Erster Kontaktpunkt von rack_line
|
nearest = nearest_points(pt, contact)[1]
|
||||||
|
print(f" 🟡 Kreisberührung bei {nearest} mit {rack_id}_{idx}")
|
||||||
print(f" 🟡 Berührpunkt bei Radius {radius:.2f}: {nearest}")
|
verbindungen.append((rack_id, other_rack_id, nearest))
|
||||||
verbindungen.append((i,j,nearest))
|
|
||||||
break
|
break
|
||||||
radius += tol_step
|
radius += tol_step
|
||||||
|
|
||||||
|
# === Ausgabe-Verbindungen ===
|
||||||
|
print("\n=== Gefundene Verbindungen ===")
|
||||||
|
for v in verbindungen:
|
||||||
|
print(v)
|
||||||
|
|||||||
Reference in New Issue
Block a user