As the sphere is being the simplest primitive there is, the test for Sphere and AABB intersection is easy. This solution works also for Sphere Cube intersection tests.
Given the following C++ structures of Point, cube (AABB) and a Sphere:
struct Point { Point() {} Point( double x, double y, double z ) : x(x) , y(y) , z(z) {} double x = 0.0; double y = 0.0; double z = 0.0; double w = 0.0; }; struct AABB { AABB() : min(), max() {} AABB( const Point & min, const Point & max ) : min(min) , max(max) {} Point min; Point max; }; struct Sphere { Sphere() : center(), radius() {} Sphere( const Point & center, double radius ) : center(center) , radius(radius) {} Point center; double radius = 0; };
And this test for determining the closest Point on AABB to a certain Point.
double SquaredDistPointAABB( const Point & p, const AABB & aabb ) { auto check = [&]( const double pn, const double bmin, const double bmax ) -> double { double out = 0; double v = pn; if ( v < bmin ) { double val = (bmin - v); out += val * val; } if ( v > bmax ) { double val = (v - bmax); out += val * val; } return out; }; // Squared distance double sq = 0.0; sq += check( p.x, aabb.min.x, aabb.max.x ); sq += check( p.y, aabb.min.y, aabb.max.y ); sq += check( p.z, aabb.min.z, aabb.max.z ); return sq; }
This test becomes easier. There is an intersection if the distance from center is larger than the radius of the sphere.
// True if the Sphere and AABB intersects bool TestSphereAABB( const Sphere & sphere, const AABB & aabb ) { double squaredDistance = SquaredDistPointAABB( sphere.center, aabb ); return squaredDistance <= (sphere.radius * sphere.radius); }
Related:
Simple AABB vs AABB collision detection
Simple Sphere-Sphere collision detection
Here is a test program testing the algorithm.
int main() { // AABB AABB aabb( Point(-1, -1, -1), Point(1,1,1) ); // Sphere 1 in the center with radius 1 Sphere s1( Point(0, 0, 0), 1 ); // Sphere 2 at x=1 with radious 1 Sphere s2( Point(1, 0, 0), 1 ); // Sphere 3 at x=3 with radious 1 Sphere s3( Point(3, 0, 0), 1 ); bool t1 = TestSphereAABB( s1, aabb ); bool t2 = TestSphereAABB( s2, aabb ); bool t3 = TestSphereAABB( s3, aabb ); std::cout << " Test 1 " << ( t1 ? "succeeded" : "failed" ) << std::endl; std::cout << " Test 2 " << ( t2 ? "succeeded" : "failed" ) << std::endl; std::cout << " Test 3 " << ( t3 ? "succeeded" : "failed" ) << std::endl; return 0; }
The output should then be:
Test 1 succeeded Test 2 succeeded Test 3 failed
All code is published at Github.
Professional Software Developer, doing mostly C++. Connect with Kent on Twitter.