• Advertisement
Sign in to follow this  

BoundingBox Collision Response

This topic is 2648 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

Probably got quite a simple question but I've tried scrawling t'internet and haven't really had much luck and I can't quite get my head around it. So I thought I would ask you lovely people for your help,

I have a bounding sphere intersecting with a bounding box:


bool BoundingBox::Intersects(BoundingSphere* checkSphere)
{
Vector3f checkDistance = checkSphere->GetPosition() - position;
if (checkDistance.Length() <= dimensions.x * 0.5f + checkSphere->radius)
{
return true;
}
return false;
}



That works fine for the moment (I know its hacked together but my box is just a square at the moment so all dimensions are the same),

I then need to push the objects apart and bounce the sphere off the box by multiplying the x or y velocity by -1 or something similar. This is what I have at the moment:


for(int j = 0; j < gameObjects.GetSize(); j++)
{
MazeWall* pWall = dynamic_cast<MazeWall*>(gameObjects.GetAtIndex(j));
if(pWall)
{
if(pWall->GetBBox()->Intersects(pMarble->bSphere))
{
if(pMarble->GetPosition().y > pWall->GetPosition().y)
{
pMarble->GetVelocity().y *= -1;
}
else if(pMarble->GetPosition().y < pWall->GetPosition().y)
{
pMarble->GetVelocity().y *= -1;
}

if(pMarble->GetPosition().x > pWall->GetPosition().x)
{
pMarble->GetVelocity().x *= -1;
}
else if(pMarble->GetPosition().x < pWall->GetPosition().x)
{
pMarble->GetVelocity().x *= -1;
}

break;
}
}
}



This doesn't work very well at all but still shows the collision detection is working fine.

How is the best way to calculate exactly where the sphere intersected the box so I can push it back and how is the best way to calculate which out the x and y velocity should be inverted.

Many thanks.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
but my box is just a square at the moment

If you intend to revise your intersection routine for circle-rectangle collisions (I assume you're really in 2D, not 3D), your time would be better spent doing that revision as whatever you come up with for a collision response for your sphere-sphere intersection* now will need to be changed then.

*Your routine treats the box as a sphere with radius 0.5f*dimensions.x.

By the way, googling results in 86,000 hits for "circle rectangle collision." Just a glance shows several just on the first page with close to "ready-to-go" code, including point-of-collision calcs. It's not really a complicated routine at all, by the way.

If you're going to go 3D, another option is to download the source code for one of the open source collision/physics engines (such as ODE) and simply adapt the code to your needs.

Share this post


Link to post
Share on other sites
OK, I've sorted out my collision detection so it should work fine now:


bool BoundingBox::Intersects(BoundingSphere* checkSphere)
{
Vector3f circleDistance;
circleDistance.x = fabs(checkSphere->GetPosition().x - position.x);
circleDistance.y = fabs(checkSphere->GetPosition().y - position.y);

if (circleDistance.x > (dimensions.x * 0.5f + checkSphere->radius)) { return false; }
if (circleDistance.y > (dimensions.y * 0.5f + checkSphere->radius)) { return false; }

if (circleDistance.x <= (dimensions.x * 0.5f)) { return true; }
if (circleDistance.y <= (dimensions.y * 0.5f)) { return true; }

float cornerDistance_sq = (circleDistance.x - dimensions.x * 0.5f) * (circleDistance.x - dimensions.x * 0.5f) +
(circleDistance.y - dimensions.y * 0.5f) * (circleDistance.y - dimensions.y * 0.5f);

return (cornerDistance_sq <= (checkSphere->radius * checkSphere->radius));

/*Vector3f checkDistance = checkSphere->GetPosition() - position;
if (checkDistance.Length() <= dimensions.x * 0.5f + checkSphere->radius)
{
return true;
}
return false; */

}



Now just to get the point of collision and calculate the response.

Thanks

Share this post


Link to post
Share on other sites
Figured it all out now so I thought I would post my code


if(pWall->GetBBox()->Intersects(pMarble->bSphere))
{
//Collision occured - check which direction to bounce in
if ((pMarble->GetPosition().x > pWall->GetPosition().x + pWall->GetDimensions().x * 0.5f && pMarble->GetVelocity().x < 0)
|| (pMarble->GetPosition().x < pWall->GetPosition().x - pWall->GetDimensions().x * 0.5f && pMarble->GetVelocity().x > 0))
{
//Collision in x direction
//pMarble->GetPosition().x -= pMarble->GetVelocity().x;
pMarble->GetVelocity().x = -pMarble->GetVelocity().x;

}
else if ((pMarble->GetPosition().y > pWall->GetPosition().y + pWall->GetDimensions().y * 0.5f && pMarble->GetVelocity().y < 0)
|| (pMarble->GetPosition().y < pWall->GetPosition().y - pWall->GetDimensions().y * 0.5f && pMarble->GetVelocity().y > 0))
{
//Collision in y direction
//pMarble->GetPosition().y -= pMarble->GetVelocity().y;
pMarble->GetVelocity().y = -pMarble->GetVelocity().y;
}

break;
}



Thanks

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement