概述
首先我们做出规定:球心坐标为center[3],半径为r,立方体左下角坐标为cube[3],边长为a,这些条件已经足够约束了,只是为了方便起见,再计算几个值:dis[3]表示球心到立方体中心的三轴距离的绝对值。
首先我们来分割一下立方体的区域,首先看下边的立方体,将立方体的每一个面做出延伸,可以发现空间被分割成了27个空间,其中在立方体外的有26个空间,其中有6个空间是与立方体的面接触,12个空间是和立方体的边接触,8个空间与立方体的顶点接触,下边就分别从这三个方面来考虑球与立方体的相交情况。
一、去除显然不满足区域
首先可以筛去很多区域,可以想到球心位于中心在立方体中心,边长为(a+2r)的立方体之外时,球不可能与立方体相交,于是有:
double maxdis = r + a / 2;
//第一种情况剔除
if (dis[0] >= maxdis || dis[1] >= maxdis || dis[2] >= maxdis)
return false;
二、球与立方体面接触
面接触的情况如下,首先球心的坐标对立方体面的投影应该在正方形之内,然后确保圆心到立方体中心的距离小于a/2+r
于是有:
//第二种情况,只要两个维度到立方体中心距离小于a/2,则球与立方体面相交
int cnt = 0;
for (int i = 0; i < 3;i++)if (dis[i] < a / 2)cnt++;
if (cnt >= 2)return true;
三、球与立方体点、边接触
3.1 球与立方体顶点接触
如果球与顶点接触,那么离球最近的零点位于球内,有:
//第三种情况
double xd = dis[0] - a / 2;
double yd = dis[1] - a / 2;
double zd = dis[2] - a / 2;
return xd * xd + yd * yd + zd * zd < r * r;
3.2 球与立方体边接触
这个和3.1很接近,因为实际上这个是3.1的简化版,一个方向上的距离为0,所以只需要计算两个即可,和上边代码类似,所以我们将3.1和3.2写在一起:
//第三种情况
double xd = max(dis[0] - a / 2, 0);
double yd = max(dis[1] - a / 2, 0);
double zd = max(dis[2] - a / 2, 0);
return xd * xd + yd * yd + zd * zd < r * r;
当求与立方体顶点相交时,dis[i]-a/2都是正的,所以和3.1代码一致,如果边相交,其中有一个值是负的,加了max可以变成0,与3.2部分吻合,所以最后的代码为:
bool check(double center[], double cube[], double r, double a) {
//立方体的中心三坐标
double cbox[3] = { cube[0] + a / 2,cube[1] + a / 2,cube[2] + a / 2 };
double dis[3] = { abs(cbox[0] - center[0]),abs(cbox[1] - center[1]) ,abs(cbox[2] - center[2]) };
double maxdis = r + a / 2;
//第一种情况剔除
if (dis[0] >= maxdis || dis[1] >= maxdis || dis[2] >= maxdis)
return false;
//第二种情况,只要两个维度到立方体中心距离小于a/2,则球与立方体面相交
int cnt = 0;
for (int i = 0; i < 3;i++)if (dis[i] < a / 2)cnt++;
if (cnt >= 2)return true;
//第三种情况
double xd = max(dis[0] - a / 2, 0);
double yd = max(dis[1] - a / 2, 0);
double zd = max(dis[2] - a / 2, 0);
return xd * xd + yd * yd + zd * zd < r * r;
}
最后
以上就是勤恳指甲油为你收集整理的空间中球与立方体的相交判定一、去除显然不满足区域 二、球与立方体面接触三、球与立方体点、边接触的全部内容,希望文章能够帮你解决空间中球与立方体的相交判定一、去除显然不满足区域 二、球与立方体面接触三、球与立方体点、边接触所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复