立方体球体相交测试?

问题描述 投票:0回答:3

最简单的方法是什么?我数学不及格,我在互联网上发现了相当复杂的公式...我希望是否有一些更简单的公式?

我只需要知道球体是否与立方体重叠,我不关心它是在哪一点等。

我也希望它能够利用两个形状都是对称的事实。

编辑:立方体在 x、y、z 轴上直线对齐

c++ intersection
3个回答
25
投票

Jim Arvo 在 Graphics Gems 2 中有一个适用于 N 维的算法。我相信您想要此页面底部的“案例 3”,针对您的案例进行清理后,它是:

bool BoxIntersectsSphere(Vec3 Bmin, Vec3 Bmax, Vec3 C, float r) {
  float r2 = r * r;
  float dmin = 0;
  for( int 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] );     
  }
  return dmin <= r2;
}

24
投票

仅仅看半空间是不够的,你还必须考虑最接近的点:

借用 Adam 的符号:

假设一个轴对齐的立方体,并让 C1 和 C2 为对角,S 为球体中心,R 为球体半径,并且两个物体都是实体:

inline float squared(float v) { return v * v; }
bool doesCubeIntersectSphere(vec3 C1, vec3 C2, vec3 S, float R)
{
    float dist_squared = R * R;
    /* assume C1 and C2 are element-wise sorted, if not, do that now */
    if (S.X < C1.X) dist_squared -= squared(S.X - C1.X);
    else if (S.X > C2.X) dist_squared -= squared(S.X - C2.X);
    if (S.Y < C1.Y) dist_squared -= squared(S.Y - C1.Y);
    else if (S.Y > C2.Y) dist_squared -= squared(S.Y - C2.Y);
    if (S.Z < C1.Z) dist_squared -= squared(S.Z - C1.Z);
    else if (S.Z > C2.Z) dist_squared -= squared(S.Z - C2.Z);
    return dist_squared > 0;
}

-1
投票
// Assume clampTo is a new value. Obviously, don't move the sphere
closestPointBox = sphere.center.clampTo(box)

isIntersecting = sphere.center.distanceTo(closestPointBox) < sphere.radius

其他一切都只是优化。

哇,-2。艰难的人群。好的,这是 Three.js 实现,它基本上逐字逐句地表达了相同的内容。 https://github.com/mrdoob/ Three.js/blob/dev/src/math/Box3.js

intersectsSphere: ( function () {

    var closestPoint;

    return function intersectsSphere( sphere ) {

        if ( closestPoint === undefined ) closestPoint = new Vector3();

        // Find the point on the AABB closest to the sphere center.
        this.clampPoint( sphere.center, closestPoint );

        // If that point is inside the sphere, the AABB and sphere intersect.
        return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );

    };

} )(),
© www.soinside.com 2019 - 2024. All rights reserved.