有没有更简单的方法来完成这个任务?我对数学不太擅长,在互联网上找到的公式非常复杂...我希望有更简单的方法。
我只需要知道一个球体是否与一个立方体重叠,我不关心它在哪个点重叠。
我也希望利用两种形状都是对称的这一事实。
编辑: 立方体沿着x、y、z轴直线对齐。
有没有更简单的方法来完成这个任务?我对数学不太擅长,在互联网上找到的公式非常复杂...我希望有更简单的方法。
我只需要知道一个球体是否与一个立方体重叠,我不关心它在哪个点重叠。
我也希望利用两种形状都是对称的这一事实。
编辑: 立方体沿着x、y、z轴直线对齐。
仅考虑半空间是不够的,还必须考虑最靠近的点:
借用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;
}
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;
}
dmin
。接着,它会检查dmin
是否在球体内部。 - boboboboSQR
定义为#define SQR(a) ((a)*(a))
。我认为你的回答中应该包含这个定义,或者功能上等效的定义,或者至少对SQR
的作用进行解释。 - undefined// 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 );
};
} )(),