Cube sphere intersection test?

后端 未结 3 529
鱼传尺愫
鱼传尺愫 2020-12-14 12:47

What\'s the easiest way of doing this? I fail at math, and i found pretty complicate formulaes over the internet... im hoping if theres some simpler one?

I just need

相关标签:
3条回答
  • 2020-12-14 13:18

    Jim Arvo has an algorithm for this in Graphics Gems 2 which works in N-Dimensions. I believe you want "case 3" at the bottom of this page: http://www.ics.uci.edu/~arvo/code/BoxSphereIntersect.c which cleaned up for your case is:

    bool BoxIntersectsSphere(Vec3 Bmin, Vec3 Bmax, Vec3 C, float r) {
      float r2 = r * r;
      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] );     
      }
      return dmin <= r2;
    }
    
    0 讨论(0)
  • 2020-12-14 13:34

    Looking at half-spaces is not enough, you have to consider also the point of closest approach:

    Borrowing Adam's notation:

    Assuming an axis-aligned cube and letting C1 and C2 be opposing corners, S the center of the sphere, and R the radius of the sphere, and that both objects are solid:

    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;
    }
    
    0 讨论(0)
  • 2020-12-14 13:38
    // Assume clampTo is a new value. Obviously, don't move the sphere
    closestPointBox = sphere.center.clampTo(box)
    
    isIntersecting = sphere.center.distanceTo(closestPointBox) < sphere.radius
    

    Everything else is just optimization.

    Wow, -2. Tough crowd. Ok, here's the three.js implementation that basically says the same thing word for word. 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 );
    
        };
    
    } )(),
    
    0 讨论(0)
提交回复
热议问题