libgdx中BoundingBox和Sphere之间的碰撞检测

在我的libgdx游戏中,我有3D BoundingBoxes和Spheres用于地图和玩家对象。 我想计算它们是否相互碰撞,以便正确模拟这些物体的运动。 我可以用什么方法来计算这些物体是否碰撞/交叉?

您可以使用以下方法:

public static boolean intersectsWith(BoundingBox boundingBox, Sphere sphere) { float dmin = 0; Vector3 center = sphere.center; Vector3 bmin = boundingBox.getMin(); Vector3 bmax = boundingBox.getMax(); if (center.x < bmin.x) { dmin += Math.pow(center.x - bmin.x, 2); } else if (center.x > bmax.x) { dmin += Math.pow(center.x - bmax.x, 2); } if (center.y < bmin.y) { dmin += Math.pow(center.y - bmin.y, 2); } else if (center.y > bmax.y) { dmin += Math.pow(center.y - bmax.y, 2); } if (center.z < bmin.z) { dmin += Math.pow(center.z - bmin.z, 2); } else if (center.z > bmax.z) { dmin += Math.pow(center.z - bmax.z, 2); } return dmin <= Math.pow(sphere.radius, 2); } 

这是模仿的

一种简单的方法,由Jim Arvo从“图形gem”进行框球交叉测试,学术出版社,1990年

可在此处找到示例C代码: http : //www.realtimerendering.com/resources/GraphicsGems/gems/BoxSphere.c

上述答案仅适用于AABB(Axis Aligned Bounding Box)。 该方法虽然简洁美观。 所以我把它扩展到包括一般边界框。 Bellow是提供与上述相同算法的最小代码。 在下面的代码中,边界框由中心和3个方向矢量R,S和T指定。每个边界框表示框的主边缘的方向和长度。

 struct OBBox{ vector3 center; vector3 S; // representing side s. vector3 R; vector3 T; /* s, r, and t take -1 or +1 representing a corner along side S, R, and T correspondingly. If one of s, r, or t is 0 then middle of corresponding edge of the non-zero side is returned. If 2 of them are 0, then middle of the plane of the corresponding side is returned. */ vector3 getCorner(int s, int r, int t) { return center + ( s*S + r*R + t*T)/2.0; } } public static boolean intersectsWith(OBBox bbox, Sphere sphere){ float dmin = 0.; vector3 center = sphere.center; float centerS = center.S; float centerR = center.R; float centerT = center.T; vector3 bminS = bbox.getCorner(-1, 0, 0); vector3 bmaxS = bbox.getCorner(1, 0, 0); vector3 bminR = bbox.getCorner(0, -1, 0); vector3 bmaxR = bbox.getCorner(0, 1, 0); vector3 bminT = bbox.getCorner(0, 0, -1); vector3 bmaxT = bbox.getCorner(0, 0, 1); if(centerS < bminS.S) { dmin += (centerS-bminS).(centerS-minS); // . means 3d dot product. else if(centerS > bmaxS) dmin += (centerS-bmaxS).(centerS-bmaxS); } if(centerR < bminR.R) { dmin += (centerR-bminR).(centerR-minR); else if(centerR > bmaxR.R) dmin += (centerR-bmaxR).(centerR-bmaxR); } if(centerT < bminT.T) { dmin += (centerT-bminT).(centerT-minT); else if(centerT > bmaxT) dmin += (centerT-bmaxT).(centerT-bmaxT); } return dmin <= (sphere.radius).(sphere.radius); }