球体与AABB间的测试
利用点至AABB的最近值,计算圆心距离AABB最近距离并与半径进行比较,若距离小于半径则相交。
计算最近平方距离
//Compute the square distance between a point 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 the 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;
}
在碰撞处理过程中,常要返回AABB上距离球心最近点,则可利用
//Given point p, return the point q on or in AABB b that is closest to p
void 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;
}
}
球体与OBB间的测试
同球体与AABB测试原理,只是更改计算最近距离方法:
点与OBB最近点
//Given point p, return point q on (or in) OBB b, closest to p
void ClosestPtPointOBB(Point p, OBB b, Point &q)
{
Vector d = p - b.c;
//Start result at center of box; make steps from there
q = b.c;
//For each OBB axis...
for(int i = 0; i < 3; i++) {
//...project d onto that axis to get the distance
//along the axis of d from the box center
float dist = Dot(d, b.u[i]);
//if distance farther than the box extents, clamp to the box
if(dist > b.e[i]) dist = b.e[i];
if(disr < -b.e[i]) dist = -b.e[i];
//Step that distance along the axis to get world coordinate
q += dist * b.u[i];
}
}
点与OBB最近平方距离
//Compute the square distance between point p and OBB b
float SqDistPointOBB(Point p, OBB b)
{
Point closest;
ClosestPtPointOBB(p, b, closest);
float sqDist = Dot(closest - p, closest - p);
return sqDist;
}
球体与三角形间的测试
同理,求最近点以及最近距离并与半径比较:
//Return true if sphere s intersects triangle ABC,false otherwise.
//The point p on ac closest to the sphere center is also returned
int TestSphereeTriangle(Sphere s, Point a, Point b, Point c, Point &p)
{
//Find point P on triangle ABC closest to sphere center
p = ClosestPtPointTrangle(s.c, a, b, c);
//Sphere and triangle intersect if the (squared) distance from sphere
//center to point p is less than the (squared) sphere radius
Vector v = p - s.c;
return Dot(v, v) <= s.r*s.r;
}
球体与多边形间的测试
可以计算多边形上距离球心最近点并与球体半径进行对比。
已知一点P求多边形距其最近点可以采用以下方法:将多边形进行三角形划分并计算P距离三角形最近点,取其中最近的。该方法对于包含n个顶点的多边形需要进行n-2次三角形测试。
另外一种解决方案是:
1.测试球体是否与多边形所在平面相交,不相交则退出并返回false;
2.测试多边形中每一条边并考查是否穿越球体,穿越则退出并返回true;
3.将球心投影至多边形平面上。执行点-多边形包含测试并查看该点是否位于多边形内部。若是,则退出并返回true,否则退出并返回false。