【问题标题】:How do you update a QuadTree after an object has moved in C++?对象在 C++ 中移动后如何更新 QuadTree?
【发布时间】:2023-03-22 04:29:01
【问题描述】:

最简单的方法是删除和插入对象,但可能有更快的方法。 (如果我想太多了,我应该用简单的方法来做,请告诉我)

这里有一些关于我的 QuadTree 的注释

  • 正在移动的对象是 AABB,可能大于 最小的 QuadTree 节点。
  • 创建子 QuadTree 时不会删除对象。那 意味着根四叉树有一个指向内部每个对象的指针 四叉树。
  • 对象作为指针存储在 QuadTree 之外的向量中。

到目前为止,每次对象移动时,它都会在根 QuadTree 上调用一个名为 Update() 的函数。它在参数中移动之前包括它自己和它过去的边界框。不过,我不确定如何制作该功能。

在这里将整个代码发布到我的 QuadTree 会使我的帖子很长,因此我创建了一个 GitHub repository 以便于阅读。

编辑:对于任何寻找答案的人this 似乎通过删除和删除对象来更新对象,并且从他在 cmets 中所做的测试来看非常有效。

【问题讨论】:

  • 这可能太多了,无法要求。如果你有任何特定的代码并且它不起作用,你可以把它放在这里..
  • 最简单的方法是删除然后重新添加对象。如果您想为移动的对象提供更好的空间分区方案,请查看“松散四叉树”

标签: c++ recursion data-structures quadtree recursive-datastructures


【解决方案1】:

真的很难做得比删除和重新插入更好,尤其是在你的情况下,因为:

  • 删除似乎超级便宜(从相应节点的向量中删除指针)
  • 在查找要将对象移动到哪个节点时,您需要像插入时一样遍历树,之后:
  • 插入非常便宜

如果性能确实是一个问题,我唯一会尝试的是从叶子中插入某种形式。假设您的树非常大,并且对象通常会移动到紧邻的节点,您可以请求在父节点中插入,如果需要,它会将其传递给其父节点。比如:

void insert_from_leaf(object* o) {
  if (!is_in_this_subtree(o)) {
    parent->insert_from_leaf(o);
    return;
  }
  find_child_node_for_object(o)->insert(0);
}

基本上,从对象来自的叶子开始遍历树可能比总是从根开始更有效,因为相邻节点倾向于共享一个近亲。

在更糟糕的情况下,您最终会做两倍的工作,因为您会一直回到根目录。在最好的情况下,源和目标都共享一个直接父级。

这将获得多大的收益完全取决于您的特定树的布局、它的大小和许多其他因素,因此您应该在实现此类之前和之后测量代码的性能。

【讨论】:

    【解决方案2】:

    解决方案很少: 您可以在每次更新时重新创建整个树。您还可以在对象移动时简单地删除和插入对象。

    另一个解决方案(在我的情况下,它给了我最好的性能)是在四叉树中只存储静态对象。我将动态对象存储在列表中(在我的游戏中,动态对象比静态对象少得多)。

    您还可以阅读其他空间数据结构,例如网格,在单元格之间移动对象要简单得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-17
      • 2013-09-09
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多