Der Bounding-Sphären-Test

Der Bounding-Sphären-Test stellt eine sehr einfache Methode zum Ausschluss unnötiger Treffer- und Kollisionsberechnungen dar. Eine Bounding-Sphäre (bounding sphere) ist schnell erzeugt, man definiert einen entsprechend großen Kollisionsradius, so dass das zugehörige Spieleobjekt vollständig von der Sphäre eingeschlossen ist.
Bei einem Trefferausschluss-Test kann die Bounding-Sphäre des Projektils vernachlässigt werden, da diese normalerweise deutlich kleiner ist als die des möglicherweise getroffenen Objekts. Ist nun der quadratische Abstand zwischen Projektil und Sphärenmittelpunkt kleiner als der quadratische Radius der Sphäre, dann liegt ein Treffer im Bereich des Möglichen (Hinweis: Man betrachtet den quadratischen Abstand, da dessen Bestimmung weniger aufwändiger ist und ohne Wurzelberechnungen auskommt).

inline bool Check_SphereHit(D3DXVECTOR3* pSpherePosition,
                            float SphereSquareRadius,
                            D3DXVECTOR3* pHitPosition)
{
    D3DXVECTOR3 DistanceVector = *pSpherePosition - *pHitPosition;

    if(D3DXVec3LengthSq(&DistanceVector) < SphereSquareRadius)
        return true;
    else
        return false;
}


Der Kollisionsausschluss-Test funktioniert auf gleiche Weise, nur werden dieses Mal die Radien beider Sphären berücksichtigt. Die Bedingung für eine mögliche Kollision lautet:

Abstand2 < Radius12 + Radius22 + 2*Radius1*Radius2

Definiert man die Kollisionsradien etwas großzügiger, dann kann auf den Mischterm verzichtet werden und die Bedingung vereinfacht sich zu:

Abstand2 < Radius12 + Radius22

Hier nun die zugehörige C/C++-Funktion:


inline bool Sphere_Sphere_Collision(D3DXVECTOR3* pSpherePosition1,
                                    float SphereSquareRadius1,
                                    D3DXVECTOR3* pSpherePosition2,
                                    float SphereSquareRadius2)
{
    D3DXVECTOR3 DistanceVector = *pSpherePosition1 - *pSpherePosition2;

    if(D3DXVec3LengthSq(&DistanceVector) < SphereSquareRadius1 +
                                           SphereSquareRadius2)
        return true;
    else
        return false;
}