【问题标题】:Figuring out ellipsoid-ellipsoid collision detection搞清楚椭球-椭球碰撞检测
【发布时间】:2017-03-27 20:51:14
【问题描述】:

我一直在为一个项目编写碰撞检测代码,并试图找出用于检测对象之间碰撞的方法。因为我使用椭球来测试关卡几何,所以我也想将它们用于对象之间的碰撞。问题在于弄清楚到底是怎么做的。我见过的一种方法将椭球体转换为球体和轴对齐的椭球体,这看起来是一个很好的解决方案,但该方法涉及找到特征向量和其他我还不太了解并且宁愿不了解的高级东西必须执行。

通过应用一系列仿射变换,应该很容易将椭球体转换为球体和倾斜椭球体。我读过倾斜的椭圆仍然是椭圆的,所以倾斜相当于旋转和缩放,我假设同样的原理适用于椭圆体。但是,我不确定如何确定新椭圆的旋转和轴长。如果我知道这一点,就很容易使椭圆体轴对齐。 在那之后,我希望能够进行扫描测试,但我不确定它的效率如何,而且我还没有弄清楚要使用的方程式,尽管我可能会用一点工作。

如果椭球体不能解决问题,我也在考虑使用其他碰撞形状,但如果能够将相同的形状用于对象世界和对象对象碰撞,那就太好了。

【问题讨论】:

  • 如果您将其中一个椭圆扭曲为球体,您可以使用Circle-ellipse intersection
  • 椭圆-椭圆交点有讨论帖here
  • 在对该主题进行了更多研究之后,看起来适当的椭球-椭球碰撞检测太复杂而无法实用。我开始使用胶囊,效果很好。

标签: collision-detection game-physics


【解决方案1】:

你说得对,这很复杂。

有一篇题为An Algebraic Approach to Continuous Collision Detection for Ellipsoids的论文

this site 的另一篇论文 here (archive) 以数学方式描述了一种算法。

Matlab 脚本Are Two Ellipsoids in Contact?,引用了上述论文。

【讨论】:

    【解决方案2】:

    免责声明:此方法在某些情况下不起作用。我在发布答案后发现了这一点。但是,对于简单的用例,结果可能已经足够好了,这就是我将这个答案留在这里的原因。

    如下图所示,我的方法返回false。

    原答案:

    我已经多次看到这个问题,但我设法想出了一个非常简单的解决方案:

    为了检查两个球体之间的碰撞,我们通常希望使用它们的半径,看看它是否小于两个球体之间的距离。

    对于椭球体,我们可以尝试做同样的事情。然而,整个椭球的半径是不同的。但这很容易实现,我们只需要知道我们想要获得半径的方向即可。

    float EllipsoidRadius(VECTOR ellipsoidRadius, VECTOR direction)
    {
        direction /= ellipsoidRadius;
        normalize(direction);
        return length(direction * ellipsoidRadius);
        // The * is just a multiplication
    }
    

    我们知道我们的方向,这只是我们的一个椭球体的位置减去另一个椭球体的位置。我们可以使用这个方向来获得两个椭球的半径,因为半径在相对两侧总是相等的(只要我们有轴对齐的椭球)。

    bool EllipsoidIntersects(POINT positionA, VECTOR sizeA, POINT positionB, VECTOR sizeB)
    {
        VECTOR direction = positionA - positionB;
        float distance = length(direction);
    
        float radiusA = EllipsoidRadius(sizeA, direction);
        float radiusB = EllipsoidRadius(sizeB, direction);
    
        return distance < radiusA + radiusB;
    }
    

    现在我们知道了两个椭球体的半径,我们可以使用良好的旧球体碰撞检查来查看它们是否发生碰撞。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 2018-06-02
      • 1970-01-01
      • 2016-08-08
      • 1970-01-01
      相关资源
      最近更新 更多