【问题标题】:Intersection-Based Collision Detection which determines the side hit确定侧面碰撞的基于交叉口的碰撞检测
【发布时间】:2013-10-27 21:55:44
【问题描述】:

您可能认为这个问题已经得到解答,但事实并非如此。因为仅仅通过在某个时间检查实际的交叉点并不能真正回答。

在图像中,“侧击”取决于最后一个位置。如果矩形是从上面来的,那么大矩形的侧面就是底部。但如果矩形来自右侧,则侧击将是右侧。

所有这一切都让我很烦恼,因为我能够为我的游戏子弹(即快速物体)实现有点复杂的碰撞检测,我认为简单的碰撞将是最简单的。但是由于我实际上必须做出响应,而不仅仅是检测,所以简单的碰撞算法变得很痛苦。

我的问题是如何实现一个实际功能强大且完美无缺的碰撞算法,该算法可以依赖于交叉点但准确,例如使用最后一个位置或一些外部资源来实际计算最佳答案。当然,这只会在角落给我带来麻烦。但它不会在任何地方造成麻烦。

(使用最后一个位置似乎是显而易见的答案,但我不知道如何处理信息以达到输出,这就是我提出这个问题的原因,我试过但现在我的大脑受伤了)

【问题讨论】:

    标签: java algorithm collision-detection


    【解决方案1】:

    我打算给出一个深入的答案,但this post 接受的答案几乎总结了我要说的内容。这是人们第一次尝试基本碰撞检测时遇到的常见问题。这个问题的解决方案比你想象的要复杂,它们基本上围绕着计算物体在碰撞点的位置。

    编辑:要确定两个物体碰撞的确切时间,您可以执行以下操作:(未测试)

    onCollide(obj1, obj2)
    {
        t = 0; //parametric value to store when objects first collided
        // calculate when the obj1's left side collides with obj2's right side
        // parametric equation is obj1.left + obj1.vel.x * t = obj2.right + obj2.vel.x * t
        // solving for t: t = (obj1.left - obj2.right) / (obj2.vel.x - obj1.vel.x)
        // we take the minimum because that is when the first sides collided
        t = math.min(t, (obj1.left - obj2.right) / (obj2.vel.x - obj1.vel.x))
        t = math.min(t, (obj1.right - obj2.left) / (obj2.vel.x - obj1.vel.x))// repeat for other sides
        t = math.min(t, (obj1.top - obj2.bottom) / (obj2.vel.y - obj1.vel.y))
        t = math.min(t, (obj1.bottom - obj2.top) / (obj2.vel.y - obj1.vel.y))
    }
    

    如果需要,您可以利用这段时间倒回整个模拟。或者您可以只查看这两个对象的状态。除了使用 min 函数,您还可以使用 if 语句并跟踪哪两个边首先发生碰撞。请记住,此计算不会跟踪在该时间步可能发生碰撞的多个对象,但通常这是一个有效的近似值。另请注意,当两个物体在一个维度上以相同速度行进但另一个维度上不一样时,您应该避免除以零。

    【讨论】:

    • 该帖子要求提供反隧道算法。就我而言,我说碰撞的物体有交叉点,也就是说,隧道不会发生。我的观点是,当我实际上可以检查交叉路口时,使用反隧道算法太昂贵了,但是要响应交叉路口,我至少需要知道哪一侧被撞到,而只有交叉路口才能知道。
    • 如果您只想知道矩形的哪一侧被击中,您可以计算碰撞时矩形的位置。我将使用一般步骤编辑我的原始帖子。
    • 我刚刚告诉你,计算碰撞时刻矩形的位置并不足以确定哪一侧被击中。这就是这个问题的全部意义所在。侧击不仅取决于确切的碰撞时刻,还取决于之前的位置。这张图片就是一个很好的例子。
    • 我想你不明白碰撞瞬间意味着什么。您的图表中描绘的不是碰撞的时刻,而是在之后的某个时刻。碰撞时刻是两个矩形第一次相交的确切时刻。您可以通过在给定速度的情况下找出两条边相交的确切时间并取第一条边相交来确定它撞到了哪一边。
    【解决方案2】:

    相交测试绝不是制造“完美”碰撞的方法。速度越高,良好回调或任何回调的可能性就越小。使用 box2d 之类的物理引擎或创建您自己的引擎(不推荐)。

    对于侧面的相交测试,您可以看到碰撞对象的边界(矩形)与其大小的关系。

    【讨论】:

    • 你错过了我的意思,反隧道碰撞算法最终会非常昂贵并且在某些特定情况下不需要,也就是说,当对象大小足够大以使其速度迭代不会标记交叉点时.这个问题的重点是在没有隧道的情况下工作的算法,它被游戏的逻辑简单地阻止了。因此,速度不是问题。
    • 这样的话,线对线交叉测试呢? keith-hair.net/blog/2008/08/08/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多