【问题标题】:Sphere-cube collision detection in Opengl?Opengl中的球体-立方体碰撞检测?
【发布时间】:2021-10-20 00:00:51
【问题描述】:

我正在尝试在 Opengl 中构建游戏。在我开始制作更好的运动机制之前,我想让碰撞工作。我有立方体碰撞工作,我有球体碰撞工作,但无法弄清楚立方体球碰撞。因为我想要它在 3d 中,所以我在对象的中心有枢轴。有人有什么建议吗?

编辑:这是我目前拥有的代码:

    bool SphereRectCollision( Sphere& sphere, Rectangle& rect) 
{ 

    //Closest point on collision box
    float cX, cY;

    //Find closest x offset 
    if( sphere.getCenterX() < rect.GetCenterX())//checks if the center of the circle is to the left of the rectangle
        cX = rect.GetCenterX(); 
    else if( sphere.getCenterX() > rect.GetCenterX() + rect.GetWidth()) //checks if the center of the circle is to the right of the rectangle
        cX = rect.GetCenterX() + rect.GetWidth(); 
    else //the circle is inside the rectagle
        cX = sphere.getCenterX(); 

    //Find closest y offset 
    if( sphere.getCenterY() > rect.GetCenterY() + rect.GetHeight() )
        cY = rect.GetCenterY(); 
    else if( sphere.getCenterY() < rect.GetCenterY() - rect.GetHeight() ) 
        cY = rect.GetCenterY() + rect.GetHeight(); 
    else 
        cY = sphere.getCenterY(); 

    //If the closest point is inside the circle 
    if( distanceSquared( sphere.getCenterX(), sphere.getCenterY(), cX, cY ) < sphere.getRadius() * sphere.getRadius() )
    { 
        //This box and the circle have collided 
        return false; 
    }

    //If the shapes have not collided 
    return true; 
}

float distanceSquared( float x1, float y1, float x2, float y2 ) 
{ 
    float deltaX = x2 - x1; 
    float deltaY = y2 - y1; 
    return deltaX*deltaX + deltaY*deltaY; 
}

【问题讨论】:

  • 您遇到了哪些问题?你能把碰撞测试的代码贴出来让我们看看有什么问题吗?
  • 立方体是否轴对齐?
  • @user1118321 我已经发布了我目前拥有的代码。我知道它需要改变。我需要它在 3d 空间中工作。
  • @Nard 现在是的,但是如果对象已经旋转,我希望它们能够工作
  • @WhyYouNoWork 你试过Separating Axis Theorem吗?

标签: c++ collision-detection collision


【解决方案1】:

我找到了解决方案。我有正确的想法,但不太知道如何执行它:

    bool SphereRectCollision( Sphere& sphere, Rectangle& rect) 
{ 
    float sphereXDistance = abs(sphere.X - rect.X);
    float sphereYDistance = abs(sphere.Y - rect.Y);
    float sphereZDistance = abs(sphere.Z - rect.Z);

    if (sphereXDistance >= (rect.Width + sphere.Radius)) { return false; }
    if (sphereYDistance >= (rect.Height + sphere.Radius)) { return false; }
    if (sphereZDistance >= (rect.Depth + sphere.Radius)) { return false; }

    if (sphereXDistance < (rect.Width)) { return true; } 
    if (sphereYDistance < (rect.Height)) { return true; }
    if (sphereZDistance < (rect.GetDepth)) { return true; }

   float cornerDistance_sq = ((sphereXDistance - rect.Width) * (sphereXDistance - rect.Width)) +
                         ((sphereYDistance - rect.Height) * (sphereYDistance - rect.Height) +
                         ((sphereYDistance - rect.Depth) * (sphereYDistance - rect.Depth)));

    return (cornerDistance_sq < (sphere.Radius * sphere.Radius));
}

【讨论】:

    【解决方案2】:

    当边缘发生碰撞时,该算法不起作用,第二组 if 条件触发但没有发生碰撞

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2011-03-15
    • 2014-04-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多