我试图在C ++中实现Sphere-Plane碰撞检测。我有一个Vector3,Plane和Sphere类。
#include "Vector3.h"
#ifndef PLANE_H
#define PLANE_H
class Plane
{
public:
Plane(Vector3, float);
Vector3 getNormal() const;
protected:
float d;
Vector3 normal;
};
#endif
我知道平面的方程是Ax + By = Cz + D = 0
,我们可以简化为N.S + d < r
,其中N是平面的法向量,S是球体的中心,r是半径球体和d是距原点的距离。如何从我的Plane和Sphere计算d的值?
bool Sphere::intersects(const Plane& other) const
{
// return other.getNormal() * this->currentPosition + other.getDistance() < this->radius;
}
答案 0 :(得分:2)
平面方程
有一个相当简单的点平面距离公式 Ax+By+Cz+D=0
(eq.10 here)
Distance = (A*x0+B*y0+C*z0+D)/Sqrt(A*A+B*B+C*C)
其中(x0,y0,z0)是点坐标。如果平面法向量(A,B,C)被归一化(单位),则可以省略分母。
(距离的符号通常对于交叉点而言并不重要)
答案 1 :(得分:1)
我在游戏中需要相同的计算。这是从点到平面的最小距离:
d = (q - p.p[0])*p.n;
除了d之外,所有变量都是3d向量(我使用的是运算符重载的简单类)。
d
:距离(标量)。
q
:在你的情况下,重点是球体的中心。
p.p[0]
:属于飞机的一个点。请注意,属于该平面的任何点都可以使用。
p.n
:垂直于飞机。
*
是点积。
点积定义为:
a*b = |a|*|b|*cos(angle)
或者,在我们的案例中:
a = q - p.p[0]
a*p.n = |a| * |p.n| * cos(angle)
由于p.n
是单一的(|p.n| == 1
):
a*p.n = |a| * cos(angle)
a
是从q
点到平面中的点的向量。 angle
是a
与飞机法线之间的角度。然后,余弦是法线上的投影,即从点到平面的垂直距离。