2D-Kollisionserkennung

Aus Spieleprogrammierer-Wiki
Wechseln zu: Navigation, Suche

Bitte beachte, dass dieser Artikel noch unvollständig ist! Hilf mit, ihn fertigzustellen.
Näheres dazu findest du ggf. auf der Diskussionsseite. Wenn du der Meinung bist, dass der Artikel vollständig ist, kannst du diesen Hinweis entfernen.

In diesem Artikel geht es um 2D-Kollisionserkennung, also die Überprüfung, ob sich zwei Objekte berühren oder schneiden. Für Anwendungen, bei denen dies eine zentrale Rolle spielt, empfiehlt sich auch ggf. der Einsatz einer Physik-Engine.

Inhaltsverzeichnis

Erkennung anhand geometrischer Figuren

Die Erkennung einer Kollision anhand der Prüfung einfacher geometrischer Figuren ist eine sehr schnelle, aber auch sehr begrenzt einsetzbare Möglichkeit zur Kollisionsprüfung.

Kollision zwischen zwei Rechtecken

Die Prüfung einer Kollision von 2 Rechtecken ist die einfachste mögliche Prüfung, sofern keine Rotation vorhanden ist. Aufgrund der daraus resultierenden hohen Geschwindigkeit kann diese Prüfung komplexeren Prüfungen voran gestellt werden, um zu testen, ob 2 Objekte nah genug aneinander sind, damit eine Kollision möglich ist.

Wenn mindestens eine Kante eines Rechtecks ein anderes Rechteck überschneidet, dann liegt eine Kollision vor. Es werden die Positionen der einzelnen Eckpunkte der Rechtecke benötigt. In diesem Beispiel wird für ein Rechteck die Position der oberen, linken Ecke und die Breite, sowie die Höhe, benutzt.

Implementierung in C++

bool rectangleCollision(const Vector& position1, float width1, float height1,
                        const Vector& position2, float width2, float height2)
{
    return position1.x < position2.x + width2  &&
           position2.x < position1.x + width1  &&
           position1.y < position2.y + height2 &&
           position2.y < position1.y + height1;
}

Implementierung in Python

def rectangleCollision(position1, width1, height1, position2, width2, height2):
    return position1[0] < position2[0] + width2  and
           position2[0] < position1[0] + width1  and
           position1[1] < position2[1] + height2 and
           position2[1] < position1[1] + height1

Implementierung in Java

boolean rectangleCollision(Vector<Float> position1, float width1, float height1,
                           Vector<Float> position2, float width2, float height2) {
    return position1.get(0) < position2.get(0) + width2  &&
           position2.get(0) < position1.get(0) + width1  &&
           position1.get(1) < position2.get(1) + height2 &&
           position2.get(1) < position1.get(1) + height1;
}

Kollision zwischen zwei Kreisen

Wenn die Distanz zwischen den Mittelpunkten zweier Kreise kleiner ist als die Summe ihrer Radien, so liegt eine Kollision vor. Also benötigen wir zum Prüfen der Kollision die Positionen und Radien der beiden Kreise. Dabei rechnen wir mit Hilfe des Satz des Pythagoras die Distanz zwischen den beiden Kreisen aus und prüfen zum Schluss, ob diese kleiner ist als die Summe beider Radien.

Implementierung in C++

bool circleCollision(const Vector& position1, float radius1,
                     const Vector& position2, float radius2)
{
    const float dx = position1.x - position2.x;
    const float dy = position1.y - position2.y;
    
    // Langsame Version, benötigt Wurzel:
    // return sqrt(dx * dx + dy * dy) <= radius1 + radius2;
    
    // Schnelle Version, vergleicht die Quadrate:
    const float radiusSum = radius1 + radius2;
    return dx * dx + dy * dy <= radiusSum * radiusSum;
}

Implementierung in Python

def circleCollision(position1, radius1, position2, radius2):
    dx = position1[0] - position2[0]
    dy = position1[1] - position2[1]
    
    # Langsame Version, benötigt Wurzel:
    # return math.sqrt(dx * dx + dy * dy) <= radius1 + radius2
    
    # Schnelle Version, vergleicht die Quadrate:
    radiusSumme = radius1 + radius2
    return dx * dx + dy * dy <= radiusSumme * radiusSumme

Implementierung in Java

boolean circleCollision(Vector<Float> position1, float radius1,
                        Vector<Float> position2, float radius2) {
    float dx = position1.get(0) - position2.get(0);
    float dy = position1.get(1) - position2.get(1);
    
    // Langsame Version, benötigt Wurzel:
    // return Math.sqrt(dx * dx + dy * dy) <= radius1 + radius2;
    
    // Schnelle Version, vergleicht die Quadrate:
    float radiusSumme = radius1 + radius2;
    return dx * dx + dy * dy <= radiusSumme * radiusSumme;
}
Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge