【问题标题】:How can I efficiently prune and merge nodes in a quadtree?如何有效地修剪和合并四叉树中的节点?
【发布时间】:2020-09-05 19:46:57
【问题描述】:

我正在使用四叉树来有效地收集某个 2D 区域中的粒子。粒子随着时间的推移逐渐消失并最终消失,因此我需要在它们死亡时将它们从四叉树中移除。

我面临的问题是如何最好地修剪四叉树以删除空节点,并在节点不再有足够的粒子来证明被分割时合并节点。

我的第一个想法是递归遍历树,检查每个子节点。如果所有 4 个节点都是空的,那么我将使用标志将其传回调用堆栈(空为 true,否则为 false),否则,我将检查每个子节点中的粒子数,以及它们是否' re 都小于 MAX_PER_NODE, 将所有粒子拉入父级并删除子级。

可能类似于以下内容(这个伪代码实际上是我写这篇文章时的意识流,所以请谨慎对待):

class QuadTreeNode
{
     public bool prune();
     public void deleteChildren(); //just assume it does what you expect...
     private:
     std::vector<ParticleType> particles;
     std::vector<QuadTreeNode*> children; // size <= 4

};

bool QuadTreeNode::prune()
{
    bool allChildrenEmpty = true;
    for(QuadTreeNode & n : children)
    {
        allChildrenEmpty &= n.prune();
    }
    //Merging could be handled by returning the number of particles instead of true/false
    //If the total number of particles falls below the max per bucket, pull the particles into the
    //current node and delete the children...
    if(allChildrenEmpty) this.deleteChildren();
    return allChildrenEmpty && (!this.particles.size());    

}

但是,这似乎效率低下,因为我觉得它需要我触摸树中的每个节点(尽管我想这比访问 每个 粒子要好)。

有没有更好的方法来实现这种修剪和合并操作?

【问题讨论】:

  • 所有粒子的寿命都一样吗?如果是这样,您可以将它们排成四个队列,每个象限一个。然后,您只需检查最早的粒子是否已过期。

标签: c++ quadtree


【解决方案1】:

假设您没有受到严重的 RAM 限制,您可以为每个节点添加一个权重计数器,表示粒子本身及其后代的总数。每当您插入或删除一个粒子时,都会对其进行更新,这实际上并不昂贵,因为您将这些节点拉入 L1 无论如何

然后当你删除时你也可以检查权重是否

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-22
    • 2020-01-18
    • 2021-07-10
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多