Box to Sphere Collision

2019-07-20 22:35发布

I need to check if a box is colliding with a sphere. I have a BoundingBox class defined with x, y, z, width, height, depth. I also have a BoundingSphere class defined with x, y, z, radius. How to I check to see if they intersect?

标签: math 3d
4条回答
迷人小祖宗
2楼-- · 2019-07-20 22:49

There's a chapter in Graphics Gems by Jim Arvo.

I guess the stale link above used to point to his code as there's "arvo" in the URL. This link works - at least right now.

查看更多
姐就是有狂的资本
3楼-- · 2019-07-20 22:51

If you want to keep the test at the level you described, you can place a bounding box around the sphere where width, height, and depth = 2r. Of course, this admits the risk of false positives for collisions at "non-polar" or "non-equatorial" points on the sphere. To solve that, you might consider building a series of hierarchical bounding boxes to increase the granularity of hit tests in these problems regions.

You might also approach the problem from a rendering level. Since you cannot render a sphere, some sort of polygonal mesh is commonly used. Hit tests between 2D (or 3D) polygons is a straightforward exercise.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-07-20 23:00

The first thing to check is if the BoundingBox for the BoundingSphere intersects. The reason for this is that it's a very simple way to rule out the more complicated math involved.

The next step would be to take each of the six planes (or twelve triangles) of the bounding box and do a distance from point to polygon test on them to the center of the sphere. If one of them is less than the radius of the sphere, then you have a hit.

Matlab code for polygon-to-point-distance: http://www.mathworks.com/matlabcentral/fileexchange/12744-distance-from-a-point-to-polygon

查看更多
祖国的老花朵
5楼-- · 2019-07-20 23:07

You just have to check all the corners of the bounding box against the distance from the center of the sphere. Here's some pseudocode:

bool collidesWith(BoundingBox b, BoundingSphere s) {
  for(Vertex v in b) {
    if(distanceBetween(v, s.center) <= s.radius)
      return true;
  }
  return false;
}
查看更多
登录 后发表回答