C++ C+中合适的球体碰撞分辨率+;

C++ C+中合适的球体碰撞分辨率+;,c++,collision-detection,game-engine,collision,C++,Collision Detection,Game Engine,Collision,我正在实现一个球体到球体的碰撞解决方案,我对从哪里开始有点困惑。第一个问题,游戏/引擎是否有一种标准的解决球到球碰撞的方法?是否只有两种标准方法可以做到这一点?或者根据需要,解决方案的差异很大 我想在我的引擎中实现这一点,我写了一个基本的概念,它推动一个球体和另一个球体(因此基本上,一个相互作用的球体可以推动另一个球体),但这只是一个超级简单的概念。我怎样才能改进它,使它更准确?(请注意,由于我仍在测试,因此代码没有优化) 一般来说,似乎缺少关于碰撞解决的可靠文档,因为这是一个更为利基的主题。我

我正在实现一个球体到球体的碰撞解决方案,我对从哪里开始有点困惑。第一个问题,游戏/引擎是否有一种标准的解决球到球碰撞的方法?是否只有两种标准方法可以做到这一点?或者根据需要,解决方案的差异很大

我想在我的引擎中实现这一点,我写了一个基本的概念,它推动一个球体和另一个球体(因此基本上,一个相互作用的球体可以推动另一个球体),但这只是一个超级简单的概念。我怎样才能改进它,使它更准确?(请注意,由于我仍在测试,因此代码没有优化)

一般来说,似乎缺少关于碰撞解决的可靠文档,因为这是一个更为利基的主题。我找到的大多数资源只涉及检测部分

bool isSphereInsideSphere(glm::vec3 sphere, float sphereRadius, glm::vec3 otherSphere, float otherSphereRadius, Entity* e1, Entity* e2)
{
    float dist = glm::sqrt((sphere.x - otherSphere.x) * (sphere.x - otherSphere.x) + (sphere.y - otherSphere.y) * (sphere.y - otherSphere.y) + (sphere.z - otherSphere.z) * (sphere.z - otherSphere.z));
    if (dist <= (sphereRadius + otherSphereRadius))
    {
        //Push code
        e1->move(-e1->xVelocity / 2, 0, -e1->zVelocity / 2);
        e2->move(e1->xVelocity / 2, 0, e1->zVelocity / 2);
    }
    return dist <= (sphereRadius + otherSphereRadius);
}
bool IsSphereInSidesSphere(glm::vec3球体,浮点球体半径,glm::vec3其他球体,浮点其他球体半径,实体*e1,实体*e2)
{
float dist=glm::sqrt((sphere.x-otherSphere.x)*(sphere.x-otherSphere.x)+(sphere.y-otherSphere.y)*(sphere.y-otherSphere.y)+(sphere.z-otherSphere.z)*(sphere.z-otherSphere.z));
如果(距离移动(-e1->xVelocity/2,0,-e1->zVelocity/2);
e2->移动(e1->xVelocity/2,0,e1->zVelocity/2);
}

使用
std::sqrt
返回距离是不必要的,比较平方长度与
(sphereRadius+otherSphereRadius)
2
可能要快得多

例如:

#include <glm/glm.hpp>
#include <iostream>
#include <cstdlib>

auto squared_length(const glm::vec3& v) {
    return std::abs(v.x * v.x + v.y * v.y + v.z * v.z);
}

class Sphere {
public:
    Sphere(const glm::vec3& Position, float Radius) :
        position{Position}, radius(Radius) {}

    bool isSphereInsideSphere(const Sphere& other) const {
        auto dist = squared_length(position - other.position);

        // compare the squared values
        if(dist <= (radius + other.radius) * (radius + other.radius)) {
            // Push code ...
            return true;
        }
        return false;
    }

private:
    glm::vec3 position;
    float radius;
};

int main() {
    Sphere a({2, 3, 0}, 2.5);
    Sphere b({5, 7, 0}, 2.5);
    std::cout << std::boolalpha << a.isSphereInsideSphere(b) << '\n'; // prints true
}
#包括
#包括
#包括
自动平方长度(常量glm::vec3&v){
返回标准::abs(v.x*v.x+v.y*v.y+v.z*v.z);
}
类球{
公众:
球体(常量glm::vec3和位置,浮动半径):
位置{位置},半径(半径){
布尔isSphereInsideSphere(常数球体和其他)常数{
自动距离=平方长度(位置-其他位置);
//比较平方值

如果(dist使用
std::sqrt
是不必要的,那么将平方长度与
(sphereRadius+otherSphereRadius)
2
进行比较可能要快得多

例如:

#include <glm/glm.hpp>
#include <iostream>
#include <cstdlib>

auto squared_length(const glm::vec3& v) {
    return std::abs(v.x * v.x + v.y * v.y + v.z * v.z);
}

class Sphere {
public:
    Sphere(const glm::vec3& Position, float Radius) :
        position{Position}, radius(Radius) {}

    bool isSphereInsideSphere(const Sphere& other) const {
        auto dist = squared_length(position - other.position);

        // compare the squared values
        if(dist <= (radius + other.radius) * (radius + other.radius)) {
            // Push code ...
            return true;
        }
        return false;
    }

private:
    glm::vec3 position;
    float radius;
};

int main() {
    Sphere a({2, 3, 0}, 2.5);
    Sphere b({5, 7, 0}, 2.5);
    std::cout << std::boolalpha << a.isSphereInsideSphere(b) << '\n'; // prints true
}
#包括
#包括
#包括
自动平方长度(常量glm::vec3&v){
返回标准::abs(v.x*v.x+v.y*v.y+v.z*v.z);
}
类球{
公众:
球体(常量glm::vec3和位置,浮动半径):
位置{位置},半径(半径){
布尔isSphereInsideSphere(常数球体和其他)常数{
自动距离=平方长度(位置-其他位置);
//比较平方值
if(dist这里是一个更简单的示例(不涉及新类)

bool IsSphereInSidesSphere(glm::vec3球体,浮点球体半径,glm::vec3其他球体,浮点其他球体半径,实体*e1,实体*e2)
{
自动增量=其他球体-球体;
自动r2=(球体半径+其他球体半径)*(球体半径+其他球体半径);
if(glm::dot(delta,delta)这里是一个更简单的示例(不涉及新类)

bool IsSphereInSidesSphere(glm::vec3球体,浮点球体半径,glm::vec3其他球体,浮点其他球体半径,实体*e1,实体*e2)
{
自动增量=其他球体-球体;
自动r2=(球体半径+其他球体半径)*(球体半径+其他球体半径);

if(glm::dot(delta,delta)我不知道规则是什么,但是问这个问题可能更合适。不要使用sqrt,squaredist,并对照检查。我不太清楚你说的不使用平方根和平方距离是什么意思。如果我不使用平方根,我无法得到距离,如果我没有距离,我无法将其平方。你能更具体一点吗举个例子吧?不要比较距离(这需要缓慢的平方根),比较距离的平方(这会更快)。有关平方根运算的速度有多慢的详细信息,请参阅。我不确定规则是什么,但问这个问题可能更合适。不要使用sqrt、squaredist并对照检查。我不太确定你说的不使用平方根和平方距离是什么意思。如果我不使用平方根,我无法获得距离,如果我没有距离我不能平方。你能更具体一点,或者举个例子吗?不要比较距离(这需要缓慢的平方根),比较距离的平方(这会更快)。有关平方根运算有多慢的更多信息,请参阅。