假设你有一个AABB(轴对齐的边界框......基本上是一个长方体)。你也有一个多面体(一个未定义形状的凸形 - 它可以是任何东西,一个长方体,一个球体,一个胶囊,所有你知道的是一个组成它的平面列表。)
现在让我们说这个AABB是一个移动对象。事实上,它正在以光速移动。但是,多面体是不可移动的。 AABB直接射向多面体,我们需要知道它到底停在哪里(它在与多面体接触后立即停止。)
有一种明显的计算方法:将运动切割成一堆微小的块,一步一步地向前移动,然后停在与多面体相交的点之前的位置。但这很慢且不准确。
有一种方法只能在2D中可行:取minkowski差异(从一个对象中减去另一个对象的所有点),从中计算一个凸包,然后在一个框中跟踪一条线。不幸的是,在3D中,凸包是一个非常强烈的计算,并且对于每个静态多面体而言,对于每个静止多面体的世界中的每个移动物体都无法真正完成,即使是通过快速计算的广泛检查。
所以问题是......计算这个的正确方法是什么,它可以完美或接近完美的准确度,并且可以在任何距离上工作?
我的方法(标记为2D的方法)是正确的方法,只是在我的结尾实施得不好?有更好的方法吗?
我在C#工作,但这个问题应该对任何语言都一样。
这是一个3D问题,但这里有一个2D图表,可以帮助理解这个问题:
答案 0 :(得分:1)
让我们将AABB视为另一个无聊的多面体 M (用于移动)。 它沿着矢量向多面体 S (静止)行进 T (旅行)。
有两种可能性:
第二种情况可以忽略,因为它意味着一个或多个角落影响 同时进行。
首先,每个多面体只能有限数量的平面参与 在碰撞中。对于 M ,只有 T 的点积的平面 正。对于 S ,只有 T 的点积为负的平面。找到所有这些飞机,并保留它们,我们称它们为碰撞参与飞机。
然后,找到 M 角落的所有坐标,并表达它们
作为时间的函数, t 。 (时间 t 时角 M_0 的 x 坐标,
{{M_0}_x}^t = T_x * t + {{M_0}_x}^0
等)
找到 M 的一个角已经过的最小 t 通过 S 的所有碰撞参与平面,你就可以了 知道何时 M 首先穿透 S 。 (这是标准linear programming problem。)
最后,重复最后两步,但移动"固定" S 朝 M , 向后沿 T (使用否定"时间", t )。在负面时间, 最大的 t S 的一个角落已经通过了所有的角落 M 的碰撞参与平面将是影响时间。您可以 翻转它上面的标志,与移动 M 得到的 t 进行比较, 至少拿一个。那将是影响的时间。你可以插上它 进入 M 的坐标,找出确切的位置。
由于 M 实际上是一个AABB,你可以很快地重建它 并从坐标中无损地消失。
(我还没有实现这一点。如果有任何部分不清楚,请告诉我。)