Files
kabellaengen/lib/linesweep_circle.py
T
2025-05-09 16:14:22 +02:00

76 lines
2.8 KiB
Python

from shapely.geometry import LineString, Point
from shapely.ops import nearest_points
"""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
]
tol = 0.5
tol_step = 0.05
rack_lines = [LineString([start, end]) for start, end in racks]
rack_endpoints = [(i, pt) for i, rack in enumerate(racks) for pt in rack]
verbindungen = []
# Überprüfe jedes Rack
for i, rack_line in enumerate(rack_lines):
print(f"\n=== Prüfe Rack {i}: {rack_line}")
for j, pt_coords in rack_endpoints:
if i == j:
continue # Eigenpunkte ignorieren
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
#alle Endpunkte prüfen, die NICHT exakt auf der Linie liegen
for j, pt_coords in rack_endpoints:
if i == j:
continue # Eigenpunkte ignorieren
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
if dist < tol:
print(f" 🔍 Punkt {pt} liegt {dist:.3f} von Linie {i} 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)
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))
break
radius += tol_step