二维空间圆形与矩形是否相交判断
设c为矩形中心,h为矩形半长度,p为圆心,r为半径。方法是计算圆心与矩形的最短距离 u,若 u 的长度小于 r 则两者相交。
- 首先利用绝对值把 p - c 转移到第一象限,下图显示不同象限的圆心也能映射至第一象限,这不影响相交测试的结果:
- 然后,把 v 减去 h,负数的分量设置为0,就得到圆心与矩形最短距离的矢量 u。下图展示了4种情况,红色的u是结果。
- 最后要比较 u 和 r 的长度,若距离少于 r,则两者相交。可以只求 u 的长度平方是否小于 r 的平方。
bool Intersection(Vector2 c, Vector2 h, Vector2 p, float r) {
Vector2 v = abs(p - c); // 第1步:转换至第1象限
Vector2 u = max(v - h, 0); // 第2步:求圆心至矩形的最短距离矢量
return dot(u, u) <= r * r; // 第3步:长度平方与半径平方比较
}
如矩形不是轴对齐矩形(AABB)而是定向矩形(OBB),可以把圆心旋转至矩形的座标系。
空间中球体和长方体相交算法
二维空间圆形和矩形相交引申到三维空间,那么就是空间中的球体和矩形相交。
我们先来看第一步:
- 首先利用绝对值把长方体的重心移动到三维空间的原点位置(0,0,0),同时球体也跟着移动,再利用绝对值将球心移动到第一象限(也就是 x>0, y>0, z>0)的空间。上面2次移动并不影响相交的测试关系
2.同样的我们计算出三维空间的h = box.max- box.center(球心坐标),并计算出 u = v- h(就是球心) 就得到球心与长方体最短距离的矢量 u
3.同样的,我们判断球体和长方体是否相交,既判断 u.squaredNorm() < squaredradius那么就认为是相交的。当然我们也要处理三维空间下 u,x <0, u.y < 0, u.z <0 的情况,只要有某一个值<0,我们便将u向量的这个值置为0
bool Intersection(Vector3 c, Vector3 h, Vector3 p, float r) {
Vector3 v = abs(p - c); // 第1步:转换至第1象限
Vector3 u = max(v - h, 0); // 第2步:求球体至长方体的最短距离矢量
return dot(u, u) <= r * r; // 第3步:长度平方与半径平方比较
}
总结:三维空间的相交检测和二维空间一摸一样,只是顶线,向量,由二维变成三维了。
以上算法参考知乎回答:
https://www.zhihu.com/question/24251545/answer/27184960