C++ AABB的球面相交检验

C++ AABB的球面相交检验,c++,math,aabb,C++,Math,Aabb,我有一个球体,我想知道我的轴对齐边界框(AABBs)是否完全、部分或根本不在球体内。我发现了很多算法,但它们只能给出部分或外部结果。任何指针?和交叉测试,至少部分交叉的结果为true,无交叉的结果为false,详情如下 现在需要检查AABB是否完全位于球体内部。通过检查所有点是否都在球体内,可以轻松完成此操作。此测试可以简化为检查AABB的两个相对顶点是否在球体内。将平方距离与球体的平方半径进行比较,可以使该测试非常快速 您可以轻松地将两个测试链接在一起: 检查AABB是否完全包含。如果没有,

我有一个球体,我想知道我的轴对齐边界框(AABBs)是否完全、部分或根本不在球体内。我发现了很多算法,但它们只能给出部分或外部结果。任何指针?

和交叉测试,至少部分交叉的结果为
true
,无交叉的结果为
false
,详情如下

现在需要检查AABB是否完全位于球体内部。通过检查所有点是否都在球体内,可以轻松完成此操作。此测试可以简化为检查AABB的两个相对顶点是否在球体内。将平方距离与球体的平方半径进行比较,可以使该测试非常快速

您可以轻松地将两个测试链接在一起:

  • 检查AABB是否完全包含。如果没有,请检查它是否部分包含
  • 反之亦然:检查AABB是否至少部分包含。如果是,请检查是否完全包含

根据每种情况发生的频率,其中一种情况可能会更好—如果您觉得需要速度,请分析您的代码。

尝试此算法:如果球体位于(或部分位于)AABB所有平面的
内侧,则球体与AABB碰撞<代码>平面内侧
表示指向AABB中心的半空间

因此,您应该检查6个AABB平面(xmin/xmax、ymin/ymax、zmin/zmax)中每个平面的球体与轴对齐平面的交点。如果按球体半径拉伸平面并检查
球体中心点
拉伸平面
,则此比较非常简单


另外,我没有在练习中尝试过。该算法基于确定三角形内点的类似方法()

Jim Arvo在“Graphics Gems”中可能已经找到了确定AABB是否与实心球体相交的最流行算法:


要解决最初的问题,现在需要更改返回条件。如果
dmin
小于
r2
,但
dmax
大于
r2
,则AABB位于球面上(部分相交)。如果
dmin
dmax
小于
r2
,则AABB完全位于球体内部。

一个明显的优化是计算球体半径的平方并与之比较;不要计算任何东西的平方根。这意味着你只做乘法和加法。@BartekBanachewicz这不适用于球体与长方体面相交的情况,但不适用于任何顶点。KaiserJohaan,你不是第一个遇到这个问题的人。谷歌应该能帮你很多忙。@Daerst啊,很好的观点。可能的重复:也就是说,如果一个球体与一个AABB共线,那么该球体在每个轴上对齐的8个点中的一个必须在它的内部,或者AABB的一条边必须在球体内部。我不认为检查AABB的任何两个相对顶点是否在球体内部就足以得出整个AABB在球体内部的结论。很容易想象这样一种情况:两个相对的顶点在球体内部,但另一个顶点仍从球体中伸出。
        dmin = 0;
        for( i = 0; i < 3; i++ ) {
            if( C[i] < Bmin[i] ) dmin += SQR( C[i] - Bmin[i] ); else
            if( C[i] > Bmax[i] ) dmin += SQR( C[i] - Bmax[i] );     
            }
        if( dmin <= r2 ) return TRUE;
switch( mode )
    {
    case 0: /* Hollow Box and Hollow Sphere */
        dmin = 0;
        dmax = 0;
        face = FALSE;
        for( i = 0; i < n; i++ ) {
            a = SQR( C[i] - Bmin[i] );
            b = SQR( C[i] - Bmax[i] );
            dmax += MAX( a, b );
            if( C[i] < Bmin[i] ) {
                face = TRUE;
                dmin += a;
                }
            else if( C[i] > Bmax[i] ) {
                face = TRUE;
                dmin += b;
                }
            else if( MIN( a, b ) <= r2 ) face = TRUE;
            }
        if( face && ( dmin <= r2 ) && ( r2 <= dmax ) ) return TRUE;
        break;
    case 2: /* Solid Box and Hollow Sphere */
        dmax = 0;
        dmin = 0;
        for( i = 0; i < n; i++ ) {
            a = SQR( C[i] - Bmin[i] );
            b = SQR( C[i] - Bmax[i] );
            dmax += MAX( a, b );
            if( C[i] < Bmin[i] ) dmin += a; else
            if( C[i] > Bmax[i] ) dmin += b;
            }
        if( dmin <= r2 && r2 <= dmax ) return TRUE;
        break;