Die räumliche Teilung ist im schlimmsten Fall immer O (N ^ 2), und darum geht es in der Informatik bei der Komplexität.
Es gibt jedoch Algorithmen, die in der linearen Zeit O (N) arbeiten . Alle basieren auf einer Art Sweep-Linie.
Grundsätzlich müssen Sie Ihre Objekte nach einer Koordinate sortieren. Angenommen, X. Wenn Sie die Sortierung jedes Mal vor der Kollisionserkennung durchführen, ist die Komplexität O (N * logN). Der Trick besteht darin, nur zu sortieren, wenn Sie der Szene Objekte hinzufügen, und später, wenn sich etwas in der Szene ändert. Das Sortieren nach Bewegung ist nicht trivial. In der unten verlinkten Veröffentlichung finden Sie einen Algorithmus, der Bewegungen berücksichtigt und dennoch in linearer Zeit arbeitet.
Dann fegen Sie von links nach rechts. Jedes Mal, wenn Ihre Sweep-Linie den Anfang eines Objekts kreuzt, wird es in eine temporäre Liste eingefügt. Jedes Mal, wenn Ihre Sweep-Linie das Objekt verlässt, nehmen Sie es aus der Liste heraus. Sie berücksichtigen Kollisionen nur innerhalb dieser temporären Liste.
Die naive Sweep-Linie ist im schlimmsten Fall auch O (N ^ 2) (Sie lassen alle Objekte die gesamte Karte von links nach rechts überspannen), aber Sie können sie O (N) machen, indem Sie sie schlauer machen (siehe Link unten). Ein wirklich guter Algorithmus wird ziemlich komplex sein.
Dies ist ein einfaches Diagramm, wie die Sweep-Linie funktioniert:
Die Linie läuft von links nach rechts. Objekte werden nach X-Koordinaten sortiert.
- Fall eins: Die ersten beiden Objekte werden geprüft. Das ist alles, was zählt.
- Fall 2: Das erste Objekt wurde geprüft und ist aus der Liste verschwunden. Zwei und drei werden geprüft.
- Fall drei: Selbst wenn dieses Objekt kollidiert, prüfen wir es nicht.
- Fall 4: Weil wir in diesem Fall nachsehen!
Algorithmen wie diese haben die Komplexität O (C * N) = O (N).
Quelle: Zwei Jahre Kurse in Computergeometrie.
Bei der Kollisionserkennung wird dies normalerweise als Sweep and Prune bezeichnet , aber die Sweep-Linienfamilie von Algortithmen ist in vielen anderen Bereichen nützlich.
Weitere empfohlene Lektüre, die meines Erachtens außerhalb des Rahmens dieser Frage liegt, aber dennoch interessant ist: Effiziente Methoden für großflächiges Sweepen und Bereinigen mit AABB-Einfügung und -Entfernung - In diesem Artikel wird ein erweiterter Algorithmus für das Sweepen und Bereinigen vorgestellt, bei dem achsenausgerichtete Begrenzungsrahmen (AABB) verwendet werden ) mit einer Sortierung, die die Bewegung berücksichtigt. Algorigthm präsentiert in den Papierarbeiten in linearer Zeit.
Beachten Sie nun, dass dies der theoretisch beste Algorithmus ist . Es bedeutet nicht, dass es verwendet wird. In der Praxis hat der O (N ^ 2) -Algorithmus mit räumlicher Aufteilung im typischen Fall eine bessere Geschwindigkeit (nahe O (N)) und eine gewisse zusätzliche Speicheranforderung. Dies liegt daran, dass die Konstante C in O (C * N) sehr hoch sein kann! Da wir normalerweise über genügend Speicher verfügen und die Objekte in typischen Fällen gleichmäßig im Raum verteilt sind, funktioniert ein solcher Algorithmus BESSER. Aber O (N) ist die Antwort auf die ursprüngliche Frage.