3
\$\begingroup\$

i have been trying to implement an aabb-sphere collision.

This is what I tried

@Override
public boolean collides(Sphere other) {
    Vector3f axis = Vector3f.sub(Vector3f.sub(max, min, null), other.getCenter(), null);
    float dist = axis.length();


    return dist < (other.getRadius() * other.getRadius());
}
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

I'm not sure how your storing your collision data or what language your working with but it looks like your trying to compare the distance from the center of your AABB to the center of your sphere. Is that correct? If so, then that is the formula for sphere to sphere collision. When working with boxes you'll need to account for their shape by measuring distance from the closest point on the edge of box to the sphere. Here is some C++ styled pseudocode with comments for AABB to Sphere collision taken from the book:

Real Time Collision Detection by Christer Ericson

Note: I've replaced all of the "out parameters" with returned objects.

// Returns true if sphere s intersects AABB b, false otherwise
public bool TestSphereAABB( Sphere s, AABB b )
{
    // Compute squared distance between sphere center and AABB
    // the sqrt(dist) is fine to use as well, but this is faster.
    float sqDist = SqDistPointAABB( s.center, b );

    // Sphere and AABB intersect if the (squared) distance between them is
    // less than the (squared) sphere radius.
    return sqDist <= s.r * s.r;
}

For calculating the distance from the closest edge of the box to an outside point you can use:

// Returns the squared distance between a point p and an AABB b
float SqDistPointAABB( Point p, AABB b )
{
    float sqDist = 0.0f;
    for( int i = 0; i < 3; i++ ){
        // for each axis count any excess distance outside box extents
        float v = p[i];
        if( v < b.min[i] ) sqDist += (b.min[i] - v) * (b.min[i] - v);
        if( v > b.max[i] ) sqDist += (v - b.max[i]) * (v - b.max[i]);
    }
    return sqDist;
}

Although the above code is faster, it may be easier to understand using the code below. And if you could also use the information about the closest point on the box to the sphere this will come in handy. Here is the pseudocode from the same book for finding it:

//Given point p, return the point q on or in AABB b that is closest to p
Point ClosestPtPointAABB( Point p, AABB b )
{
    Point q;
    // For each coordinate axis, if the point coordinate value is
    // outside box, clamp it to the box, else keep it as is
    for( int i = 0; i < 3; i++ ) {
        float v = p[i];
        if( v < b.min[i] ) v = b.min[i]; // v = max( v, b.min[i] )
        if( v > b.max[i] ) v = b.max[i]; // v = min( v, b.max[i] )
        q[i] = v;
    }
    return q;
}

You can take the point you get from ClosestPtPointAABB() and calculate the distance between it, and the sphere's center and then compare that distance to the sphere's radius to see if it collides.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .