2D Kollisionserkennung - Teil 1: Kreis vs Kreis

Fast jedes Spiel benötigt eine Form der Kollisionserkennung. Dabei gibt es verschiedene Arten von Kollisionen. Ich beschränke mich hier erst mal auf konvexe Körper. Konkave Körper lassen sich aber in der Regel aus mehreren konvexen Körpern zusammensetzten.

In diesem Tutorial beschäftigen wir uns mit der Kollision zwischen zwei Kreisen. Diese werden durch eine Position und einem Radius beschrieben. Der Ursprung des Kreises befindet sich in der Mitte des Kreisen.

Zwei Kreise kollidieren immer genau dann, wenn der Abstand vom Mittelpunkt des Kreises aus kleiner ist als der Radius beider Kreise zusammen. Ist der Abstand kleiner, findet keine Überschneidung der Kreise statt:

Keine Überschneidung:

Keine Überschneidung der Kreise

Die Kreise überschneiden sich:

Überschneidung der Kreise

Die schwarze Linie (beginnt in der Mitte der Kreise und ist unter den Linien der Radien etwas undeutlich zu sehen) stellt den Abstand dar, während der Pfeil vom Mittelpunkt der Kreise zur Außenhülle den Radius darstellt. Im 2. Bild erkennt man, dass sich die Pfeile der Radien der beiden Kreise überschneiden. Somit ist die Summe der beiden Radien nun größer als der Abstand zwischen den Kreis Mittelpunkten und es liegt eine Kollision vor:

private boolean isColliding(Circle objA, Circle objB) {
	Vector2f positionA = objA.getPosition();
	Vector2f positionB = objB.getPosition();
	// Ermittel den Richtungsvektor zwischen Kreis B und Kreis A
	Vector2f distanceVec = positionA.subtract(positionB);
	// Ermittel die länge des Richtungsvektors. 
	// Die länge ist der Abstand zwischen den beiden Kreis Mittelpukten
	float distance = distanceVec.length();
	// Wenn der gerade ermittelte Abstand kleiner ist als die Summe
	// der beiden Radien der Kreise, liegt eine Kollision vor
	if (distance < objA.getRadius() + objB.getRadius()) {
		return true;
	}
	return false;
}

In den ersten beiden Zeilen speichern wir die Position der beiden Kreise. Die Klasse Vector2f ist eine einfache selbst erstellte Klasse, die zwei float Werte speichert und ein paar grundlegende Vektoroperationen beherrscht. Danach ermitteln wir den Richtungsvektor zwischen den beiden Mittelpunkten. Dabei spielt es keine Rolle, ob ihr den Richtungsvektor von A zu B oder B zu A ermittelt. Die Länge ist auf jeden Fall die gleiche. Die Länge ermitteln wir im nächsten Schritt. Jetzt haben wir den Abstand der beiden Kreis Mittelpunkte zueinander. Jetzt prüfen wir nur noch ob die Summe der beiden Radien größer ist als der gerade ermittelte Abstand und geben true zurück wenn dies zutrifft. Ist er nicht kleiner, liegt keine Kollision vor und wir geben false zurück.

Source Code:
Sourcecode des Tutorials auf Github