我一直在研究项目的碰撞检测代码,我正在试图找出用于检测对象之间碰撞的方法。由于我使用椭球来测试水平几何,我也想将它们用于对象之间的碰撞。问题是弄清楚具体如何。我见过的一种方法是将椭球转换为球体和轴对齐的椭圆体,这看起来是一个很好的解决方案,但该方法涉及找到我不太了解的特征向量和其他高级东西,而不是必须实施。
通过应用一系列仿射变换,将椭球转换为球体和倾斜椭球应该很容易。我已经读过倾斜的椭圆仍然是椭圆形的,所以偏斜相当于旋转和缩放,我认为同样的原理适用于椭圆体。但是,我不确定如何确定新椭圆的旋转和轴长度。如果我知道这一点,很容易使椭球轴对齐。 在那之后,我希望能够进行扫描测试,但是我不确定它的效率是多少,而且我还没有弄清楚要使用的方程式,尽管我可能会想到这些一点工作。
如果椭圆体没有用,我也在考虑使用其他碰撞形状,但能够对物体世界和物体 - 物体碰撞使用相同的形状真的很不错。
答案 0 :(得分:1)
你是对的,这很复杂。
有一篇题为An Algebraic Approach to Continuous Collision Detection for Ellipsoids
的论文来自here的另一篇论文archive(this site)以数学方式描述了算法。
Matlab脚本Are Two Ellipsoids in Contact?,参考上述论文。
答案 1 :(得分: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;
}
现在我们知道了两个椭圆体的半径,我们可以使用良好的旧球体碰撞检查来查看它们是否发生碰撞。