Leider verstehe ich den Sweep-Line-Algorithmus immer noch nicht so gut . Alle Artikel und Lehrbücher zum Thema sind bereits gelesen, das Verständnis ist jedoch noch weit entfernt. Nur um es klarer zu machen, versuche ich so viele Übungen wie möglich zu lösen. Aber wirklich interessante und wichtige Aufgaben sind für mich immer noch eine Herausforderung.
Die folgende Übung habe ich in den Vorlesungsunterlagen von Line Segment Intersection des allmächtigen Jeff Erickson gefunden.
Aufgabe 2. Beschreiben und analysieren Sie einen Sweepline-Algorithmus, um bei Kreisen in der Ebene zu bestimmen, ob sich zwei in O ( n log n ) überschneiden . Jeder Kreis wird durch seinen Mittelpunkt und seinen Radius spezifiziert, sodass die Eingabe aus drei Arrays X [ 1 .. n ] , Y [ 1 .. n ] und R [ 1 .. n ] besteht . Stellen Sie sicher, dass Sie die Grundelemente auf niedriger Ebene korrekt implementieren.
Versuchen wir, eine komplexe Sache zu vereinfachen. Was wissen wir über die Überschneidung von Kreisen? Welches Analogon kann mit Schnittpunkt von Linien gefunden werden. Zwei Linien können sich kreuzen, wenn sie benachbart sind. Welche Eigenschaft sollten zwei Kreise haben, um sich zu kreuzen? Sei der Abstand zwischen dem Mittelpunkt der Kreise, r 0 und r 1 Mittelpunkt der Kreise. Betrachten Sie einige Fälle:
Fall 1: Wenn dann gibt es keine Lösungen, die Kreise sind getrennt.
Fall 2: Wenn dann gibt es keine Lösungen, weil ein Kreis im anderen enthalten ist.
Fall 3: Wenn und r 0 = r 1, fallen die Kreise zusammen und es gibt unendlich viele Lösungen.
Es sieht also so aus, als wären die Kreuzungsbedingungen bereit. Natürlich kann es sich um falsche Bedingungen handeln. Bitte korrigieren Sie, wenn es so ist.
Algorithmus. Jetzt müssen wir etwas gemeinsam zwischen zwei sich überschneidenden Kreisen finden. Bei einem Schnittpunkt analog zur Linie müssen die Einfügebedingung und die Löschbedingung für die Ereigniswarteschlange vorhanden sein. Angenommen, der Ereignispunkt ist die x-Koordinate des ersten und des letzten Punkts, den die vertikale Sweep-Linie berührt. Beim ersten Punkt fügen wir einen Kreis in den Status ein und prüfen, ob sich die drei oben genannten Fälle mit den nächstgelegenen Kreisen überschneiden. Beim letzten Punkt löschen wir den Kreis aus dem Status .
Es sieht so aus, als ob es für den Sweep-Line-Algorithmus ausreicht. Wenn etwas nicht stimmt oder wenn etwas nicht stimmt, können Sie uns gerne Ihre Gedanken mitteilen.
Nachtrag :
Ich füge einen Kreis ein, wenn die vertikale Sweep-Linie den Kreis zum ersten Mal berührt, und entferne einen Kreis aus dem Status, wenn die Sweep-Linie den Kreis zum letzten Mal berührt. Die Prüfung auf Schnittpunkte sollte für den nächsten vorherigen Kreis erfolgen. Wenn wir einen Kreis zum Status hinzugefügt haben und es bereits einen anderen Kreis gab, den wir zuvor hinzugefügt haben und der noch vorhanden war, wurde der durchlässige Kreis nicht "geschlossen", sodass möglicherweise eine Kreuzung vorliegt.
status
die Kreise, die derzeit die Sweep-Linie schneiden , beibehalten werden. Angenommen, Sie haben zurzeit 100 Kreise in status
, verarbeiten ein Einfügeereignis und fügen den 101. Kreis ein. Wie viele Kreise vergleichen Sie, um die Schnittmenge zu ermitteln? Wie wählen Sie die zu vergleichenden Kreise aus?