C++ 平面球体碰撞检测

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

我正在尝试用 C++ 实现球面碰撞检测。我有一个 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 是距离从原点。如何根据平面和球体计算 d 值?

bool Sphere::intersects(const Plane& other) const
{
    // return other.getNormal() * this->currentPosition + other.getDistance() < this->radius;
}
c++ geometry collision-detection
3个回答
4
投票

我需要在我制作的游戏中进行相同的计算。这是从点到平面的最小距离:

distance = (q - plane.p[0])*plane.normal;

除了

distance
,所有变量都是 3D 向量(我使用一个通过运算符重载制作的简单类)。

distance
:点到平面的最小距离(标量)。

q
:点(3D 向量),在您的情况下是球体的中心。

plane.p[0]
:属于平面的点(3D 向量)。请注意,属于平面的任何点都可以工作。

plane.normal
:垂直于平面。

*
是向量之间的点积。可以在 3D 中实现为
a*b = a.x*b.x + a.y*b.y + a.z*b.z
并产生标量。

说明

点积定义为:

a*b = |a| * |b| * cos(angle)

或者,在我们的例子中:

a = q - plane.p[0]
a*plane.normal = |a| * |plane.normal| * cos(angle)

由于

plane.normal
是酉 (
|plane.normal| == 1
):

a*plane.normal = |a| * cos(angle)

enter image description here

a
是从点
q
到平面上一点的向量。
angle
a
与平面法线之间的角度。那么,余弦就是法线的投影,也就是点到平面的垂直距离。


3
投票

用平面方程计算点平面距离有相当简单的公式

Ax+By+Cz+D=0
(这里eq.10

Distance = (A*x0+B*y0+C*z0+D)/Sqrt(A*A+B*B+C*C)

其中 (x0,y0,z0) 是点坐标。如果您的平面法向量 (A,B,C) 已标准化(单位),则可以省略分母。

(对于交叉路口来说,距离标志通常并不重要)


0
投票

但是,如果平面是由一组顶点定义的,并且其边的大小不均匀,该怎么办?

© www.soinside.com 2019 - 2024. All rights reserved.