找出椭圆体 - 椭圆体碰撞检测

时间:2012-08-30 06:28:54

标签: collision-detection game-physics

我一直在研究项目的碰撞检测代码,我正在试图找出用于检测对象之间碰撞的方法。由于我使用椭球来测试水平几何,我也想将它们用于对象之间的碰撞。问题是弄清楚具体如何。我见过的一种方法是将椭球转换为球体和轴对齐的椭圆体,这看起来是一个很好的解决方案,但该方法涉及找到我不太了解的特征向量和其他高级东西,而不是必须实施。

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

如果椭圆体没有用,我也在考虑使用其他碰撞形状,但能够对物体世界和物体 - 物体碰撞使用相同的形状真的很不错。

2 个答案:

答案 0 :(得分:1)

你是对的,这很复杂。

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

的论文

来自here的另一篇论文archivethis site)以数学方式描述了算法。

Matlab脚本Are Two Ellipsoids in Contact?,参考上述论文。

答案 1 :(得分:1)

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

我的方法在如下图所示的情况下返回false。

enter image description here

原始答案:

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

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

使用椭球,我们可以尝试做同样的事情。但是,椭圆体的半径不同。但这很容易实现,我们只需要知道我们想要获得半径的方向。

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;
}

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