2D网格中对象的碰撞处理

时间:2017-02-21 00:16:37

标签: java algorithm multidimensional-array collision

我正在开发一个Java模拟,其中对象在2D网格中移动。网格中的每个单元格只能由一个单元格占据,并且对象通过从一个单元格移动到另一个单元格来移动。

这比理论上更具理论性,但有没有人有关于如何与此网格进行冲突处理的想法?是否有人用于处理网格状世界中的碰撞的算法?

请注意,我不是在谈论碰撞检测,因为这是微不足道的,因为对象从一个单元格移动到另一个单元格。我正在谈论碰撞处理,这可能会非常复杂。

Ex:对象A希望移动到与对象B相同的位置,并且对象C希望移动到对象B的当前位置。由于每个单元格只能包含一个对象,如果对象A能够移动到所需的位置,这将导致对象B保持静止,从而导致对象C也保持静止。

可以想象,这可能会产生更长的需要处理的碰撞链。

是否有人使用过可以帮助解决这个问题的算法或方法?如果搜索结果没有使用碰撞 detection 算法,则几乎不可能搜索此问题。

编辑:所有对象在同一时间移动。我想限制必须保持静止的对象数量,所以我更喜欢先处理具有较长碰撞链的对象(如本例中的对象B)。

2 个答案:

答案 0 :(得分:1)

根据与OP的讨论,对象应以最大化所有移动对象的数量的方式移动。

带有引用的对象形成树林。如果对象A引用B对象占用的单元格,我们可能会说B是树中A。因此,对象对应于节点,引用对应于树中的边。每棵树的根中都会有一些空单元格(所以当空单元格对应一个节点时实际上就是这种情况)。树没有公共节点。

在继续前进之前,我们必须承认可能存在周期的情况。像这样:

[A] -> [B]                 
 ^      v       or     [A] <=> [B]
[D] <- [C]                 

可以轻松识别这些周期。某些对象可能直接或间接地引用循环对象,也形成树。循环只能在树的根中发生。

让我们说我们建造了所有树木。现在问题是我们如何解决冲突?请记住,我们希望最大化移动节点的数量。冲突对应于具有多于1个孩子的节点。

cycle-root 树中,除了仅移动循环对象而不移动树中的任何其他对象外,我们没有任何其他选项。很明显,我们不能采取另一种方式。

首先,在 empty-cell-root 树中,我们必须决定将哪个根子项放在根空单元格上。然后我们将有一个新的空单元格,我们将不得不采取相同的决定。依此类推,直到 leaf 节点。为了最大化移动节点的数量,我们必须将最长的链从根到某个叶子并移动其节点。所有其他节点都不移动。这可以通过使用一些递归函数遍历树并为每个节点计算以下函数 f 来轻松完成 f leaf = 0 f node = MAX(f child1 ,f child2 ,...)+ 1 。因此,上述决定是选择具有最大 f 的子节点。

    *
   /|\
  A B C         The optimal move path  is   * <- C <- E <- H
 /   /|\
D   E F G
   /
  H

答案 1 :(得分:0)

提前“检查”/“下一步”将导致难以计算甚至爆炸。

相反,你可以(并行)使用检查“哪个粒子可以移动到这个位置?”在每个细胞上。为此,您需要在每个单元格中具有速度矢量的速度图。然后向后跟随该向量,找到一个单元格。如果有粒子,请将其送到牢房。

这样就不会发生冲突,因为每个单元只执行一次操作。只需从负速度矢量的终点获得最接近的单元格。

计算起来有点棘手,因为速度可能无法完全落在细胞中心。对于运动/宏观效果的平等,需要概率(如果它非常靠近角落而不是中心)。

因此,仅在细胞指数上存在竞争条件,并且移动的随机性(或粒子拾取取决于与细胞中心的距离)可以容忍

在量子物理学中,粒子可以跳过墙壁的其他部分,静止不动(即使它不应该),并做一些对经典物理学来说不自然的事情。因此,如果分辨率很高,并且速度不高于地图大小,它应该看起来很自然,尤其是当多个细胞竞争从另一个细胞中获取粒子时的随机性。

多次通过:

  • 计算哪些细胞需要从哪些细胞中收集,
  • 计算概率然后赢得细胞
  • 奖金细胞平行地从源细胞中收集它们的粒子。
  • (不推荐),如果仍然存在具有速度的未拾取粒子,则进行每粒子计算以移动它们(如果它们的目标单元格为空),应该进一步减少静止粒子。
  • 将细胞上的粒子速度扩散几次(使用2D模板),以便在下一次迭代中使用。(这个很容易处理复杂的碰撞计算,并且以一种令人尴尬的平行方式处理,对于多线程-gpgpu很有用)(如果是粒子)只能去最近的邻居,这也有助于知道哪一个,即使没有任何优先权也没有概率,因为每个细胞以速度扩散来抵消相邻细胞的速度)

检查Gauss-Seidel(https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method)方法以解决许多线性方程式。

计算是在细胞而不是粒子上进行的,因此地图边界将是防弹的,并且计算可以在所有核心之间平均分配。

示例:

粒子A下降

粒子B向右走

他们正处于碰撞过程中

求解速度图平衡状态(Gauss-Seidel)

现在粒子A的单元格具有向下+向右的速度

与B

相同 好像他们碰撞了但是他们还在他们的牢房里。

用它们的细胞速度移动它们会使它们看起来像碰撞一样。