Versuch mit anderem GPT Ansatz für Intersection von Diagonalen. Wenig Erfolg

This commit is contained in:
2025-05-08 15:43:35 +02:00
parent 1a63947a8a
commit a3a47a6af4
+191 -12
View File
@@ -1,5 +1,7 @@
from bisect import bisect_left, bisect_right
from bisect import bisect_left, bisect_right,insort
import unittest
from collections import namedtuple
import math
def find_intersections(horizontal_segments, vertical_segments, epsilon=0.0):
@@ -27,22 +29,199 @@ def find_intersections(horizontal_segments, vertical_segments, epsilon=0.0):
return intersections
class TestStringMethods(unittest.TestCase):
def test_sweep(self):
horizontal = [((1, 2), (5, 2)), ((3, 4), (7, 4))]
vertical = [((4, 1), (4, 5)), ((6, 3), (6, 6))]
a = find_intersections(horizontal, vertical)
self.assertEqual( [(4,2),(4,4),(6,4)], a)
def test_tol(self):
horizontal = [((0, 0), (10, 0))]
vertical = [((4, 0.6), (4, 5)), ((6, 0.2), (6, 6)),((8,-0.2),(8, 4))]
Point = namedtuple('Point', ['x', 'y'])
Segment = namedtuple('Segment', ['p1', 'p2'])
b = find_intersections(horizontal, vertical, 0.5)
self.assertEqual( length(b), 2)
def ccw(a, b, c):
return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x)
def intersect(s1, s2, tol=1e-8):
"""Erweiterte Schnittprüfung mit Toleranz."""
# Klassische Schnitttest
a, b = s1.p1, s1.p2
c, d = s2.p1, s2.p2
if ccw(a, c, d) != ccw(b, c, d) and ccw(a, b, c) != ccw(a, b, d):
return True
# Zusätzliche Toleranzprüfung: Mindestabstand der Segmente
return segment_distance(s1, s2) < tol
def point_distance(p1, p2):
return math.hypot(p1.x - p2.x, p1.y - p2.y)
def point_segment_distance(p, seg):
"""Abstand eines Punkts zu einem Segment."""
x, y = p.x, p.y
x1, y1 = seg.p1.x, seg.p1.y
x2, y2 = seg.p2.x, seg.p2.y
dx, dy = x2 - x1, y2 - y1
if dx == dy == 0:
return point_distance(p, seg.p1)
t = max(0, min(1, ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy)))
nearest = Point(x1 + t * dx, y1 + t * dy)
return point_distance(p, nearest)
def segment_distance(s1, s2):
"""Kleinster Abstand zweier Segmente."""
return min(
point_segment_distance(s1.p1, s2),
point_segment_distance(s1.p2, s2),
point_segment_distance(s2.p1, s1),
point_segment_distance(s2.p2, s1),
)
def segment_cmp_x(segment, x):
p1, p2 = segment.p1, segment.p2
if p1.x == p2.x:
return min(p1.y, p2.y)
slope = (p2.y - p1.y) / (p2.x - p1.x)
y = p1.y + slope * (x - p1.x)
return y
def schnittpunkttest(segments, tolerance=1e-8):
events = []
for seg in segments:
left = seg.p1 if seg.p1.x < seg.p2.x else seg.p2
right = seg.p2 if seg.p1.x < seg.p2.x else seg.p1
events.append((left.x, True, seg))
events.append((right.x, False, seg))
events.sort()
L = []
for x, is_left, seg in events:
key = lambda s: segment_cmp_x(s, x)
idx = bisect_left(L, seg, key=key)
if is_left:
insort(L, seg, key=key)
idx = bisect_left(L, seg, key=key)
pred = L[idx - 1] if idx > 0 else None
succ = L[idx + 1] if idx < len(L) - 1 else None
if (pred and intersect(pred, seg, tolerance)) or (succ and intersect(succ, seg, tolerance)):
#print("ja")
return
else:
idx = bisect_left(L, seg, key=key)
if idx < len(L) and L[idx] == seg:
pred = L[idx - 1] if idx > 0 else None
succ = L[idx + 1] if idx < len(L) - 1 else None
L.pop(idx)
if pred and succ and intersect(pred, succ, tolerance):
#print("ja")
return
#print("nein")
def sektionen(segmente, tolerance):
laenge = len(segmente)
lseg = list()
for r1 in range(laenge):
s1 = segmente[r1]
p1 = Point(s1[0][0],s1[0][1])
p2 = Point(s1[1][0],s1[1][1])
seg1 = Segment( p1, p2 )
lseg.append(seg1)
schnittpunkttest(lseg, tolerance)
# class TestSweepMethods(unittest.TestCase):
# def test_sweep(self):
# horizontal = [((1, 2), (5, 2)), ((3, 4), (7, 4))]
# vertical = [((4, 1), (4, 5)), ((6, 3), (6, 6))]
# a = find_intersections(horizontal, vertical)
# self.assertEqual( [(4,2),(4,4),(6,4)], a)
# def test_tol_hor(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# schnittpunkt zwischen gegebener horizontalen und zu kurzen vertikalen
# """
# horizontal = [((0, 0), (10, 0))]
# vertical = [((4, 0.6), (4, 5)), ((6, 0.2), (6, 6)),((8,-0.2),(8, 4))]
# b = find_intersections(horizontal, vertical, 0.5)
# self.assertEqual( len(b), 2)
# self.assertEqual( [(6,0),(8,0)], b)
# def test_tol_ver(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# schnittpunkt zwischen gegebener vertikalen und zu kurzen horizontalen
# """
# horizontal = [((0.2, 0), (9.8, 0))]
# vertical = [((0, 0), (0, 10)), ((10, 0), (10, 10))]
# b = find_intersections(horizontal, vertical, 0.5)
# self.assertEqual( len(b), 2)
# self.assertEqual( [(6,0),(8,0)], b)
# def test_tol_diag(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# Horizontale mit Diagonalen
# """
# horizontal = [((0, 0), (5, 0))]
# diagonal = [((0, -5), (10, 5))]
# b = find_intersections(horizontal, diagonal, 0.5)
# self.assertEqual( len(b), 1)
# self.assertEqual( [(0,0),(0,0)], b)
class TestScanLineAllgMethods(unittest.TestCase):
# def test_sweep(self):
# seks = [((1, 2), (5, 2)), ((3, 4), (7, 4)), ((4, 1), (4, 5)), ((6, 3), (6, 6))]
# a = sektionen(seks)
# self.assertEqual( [(4,2),(4,4),(6,4)], a)
# def test_tol_hor(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# schnittpunkt zwischen gegebener horizontalen und zu kurzen vertikalen
# """
# seks = [((0, 0), (10, 0)), ((4, 0.6), (4, 5)), ((6, 0.2), (6, 6)),((8,-0.2),(8, 4))]
# b = sektionen(seks, 0.5)
# self.assertEqual( len(b), 2)
# self.assertEqual( [(6,0),(8,0)], b)
# def test_tol_ver(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# schnittpunkt zwischen gegebener vertikalen und zu kurzen horizontalen
# """
# seks = [((0.2, 0), (9.8, 0)), ((0, 0), (0, 10)), ((10, 0), (10, 10))]
# b = sektionen(seks, 0.5)
# self.assertEqual( len(b), 2)
# self.assertEqual( [(6,0),(8,0)], b)
# def test_tol_diag(self):
# """Testet die Anzahl der Schnittpunkte bei gegebener Toleranz
# Horizontale mit Diagonalen
# """
# seks = [((0, 0), (5, 0)), ((0, -5), (10, 5))]
# b = sektionen(seks, 0.5)
# self.assertEqual( len(b), 1)
# self.assertEqual( [(6,0),(8,0)], b)
def test_chatgpt(self):
s1 = Segment(Point(0, 0), Point(4, 4)) # Diagonale
s2 = Segment(Point(0, 4), Point(4, 0)) # Kreuzt s1 → Schnitt
s3 = Segment(Point(5, 5), Point(6, 6)) # Weit entfernt, kein Schnitt
s4 = Segment(Point(1, 1), Point(1, 3)) # Schneidet s1 → weiterer Schnitt
schnittpunkttest([s1, s2, s3, s4], tolerance=1e-8) # Ausgabe: ja
if __name__ == '__main__':
unittest.main()