2

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

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

如果椭圆体不起作用,我也在考虑使用其他碰撞形状,但是能够为对象世界和对象对象碰撞使用相同的形状真的很好。

4

2 回答 2

1

你是对的,这很复杂。

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

该站点的另一篇论文(存档)在数学上描述了一种算法。

Matlab脚本是两个椭圆体接触吗?,其中引用了上述论文。

于 2013-03-29T07:28:41.410 回答
1

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

在如下图所示的情况下,我的方法返回 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;
}

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

于 2017-03-27T12:29:54.877 回答