Um Ihre Effizienz zu steigern, versuchen Sie, 99% der "Einheiten", die sich nicht in der Nähe der Zieleinheit befinden, mithilfe eines sehr kostengünstigen Kontrollkästchens trivial zurückzuweisen. Und ich hoffe, Sie könnten dies tun, ohne Ihre Daten räumlich zu strukturieren. Wenn alle Ihre Einheiten in einer flachen Datenstruktur gespeichert sind, können Sie versuchen, sie von Anfang bis Ende zu durchlaufen, und zunächst überprüfen, ob sich die aktuelle Einheit außerhalb des Begrenzungsrahmens der gewünschten Einheit befindet.
Definieren Sie einen übergroßen Begrenzungsrahmen für die Einheit von Interesse, sodass er sicher Elemente ablehnen kann, die nicht als "nahe" angesehen werden können. Die Prüfung auf Ausschluss von einem Begrenzungsrahmen könnte billiger als eine Radiusprüfung sein. Bei einigen Systemen, bei denen dies getestet wurde, wurde jedoch festgestellt, dass dies nicht der Fall ist. Die beiden sind fast gleich stark. Dies bearbeitete nach langer Diskussion weiter unten.
Erstens: 2D-Begrenzungsrahmenclip.
// returns true if the circle supplied is completely OUTSIDE the bounding box, rectClip
bool canTrivialRejectCircle(Vertex2D& vCentre, WorldUnit radius, Rect& rectClip) {
if (vCentre.x + radius < rectClip.l ||
vCentre.x - radius > rectClip.r ||
vCentre.y + radius < rectClip.b ||
vCentre.y - radius > rectClip.t)
return true;
else
return false;
}
Im Vergleich zu so etwas (in 3D):
BOOL bSphereTest(CObject3D* obj1, CObject3D* obj2 )
{
D3DVECTOR relPos = obj1->prPosition - obj2->prPosition;
float dist = relPos.x * relPos.x + relPos.y * relPos.y + relPos.z * relPos.z;
float minDist = obj1->fRadius + obj2->fRadius;
return dist <= minDist * minDist;
}.
Wenn das Objekt nicht einfach zurückgewiesen wird, führen Sie einen teureren und genaueren Kollisionstest durch. Aber Sie suchen nur nach Nähe, deshalb ist der Kugeltest dafür geeignet, aber nur für 1% der Objekte, die die triviale Zurückweisung überleben.
Dieser Artikel unterstützt die Box für triviale Ablehnung.
http://www.h3xed.com/programming/bounding-box-vs-bounding-circle-collision-detection-performance-as3
Wenn Sie mit diesem linearen Ansatz nicht die Leistung erhalten, die Sie benötigen, ist möglicherweise eine hierarchische Datenstruktur erforderlich, über die die anderen Poster bereits gesprochen haben. R-Bäume sind eine Überlegung wert. Sie unterstützen dynamische Änderungen. Sie sind die Bäume der räumlichen Welt.
Ich wollte nur nicht, dass Sie sich die Mühe machen, eine solche Komplexität einzuführen, wenn Sie sie vermeiden könnten. Und was ist mit den Kosten für die Aktualisierung dieser komplexen Datenstruktur, wenn sich Objekte mehrmals pro Sekunde bewegen?
Bedenken Sie, dass ein Gitter eine tiefe Geodatenstruktur mit einer Ebene ist. Dieses Limit bedeutet, dass es nicht wirklich skalierbar ist. Je größer die Welt wird, desto mehr Zellen müssen abgedeckt werden. Irgendwann wird diese Anzahl von Zellen selbst zu einem Leistungsproblem. Für eine Welt mit einer bestimmten Größe bedeutet dies jedoch eine massive Leistungssteigerung gegenüber einer räumlichen Aufteilung.