QuadTrees - 当内部项目移动时如何更新
我已经实现了一个工作四叉树。它细分二维空间以容纳项目,通过尽可能小的四边形(最大为最小区域)上的边界框(x,y,宽度,高度)来标识。
我的代码基于此实现(我的代码是 Lua 而不是 C#): http:// /www.codeproject.com/KB/recipes/QuadTree.aspx
我已经能够成功实现插入和删除。我现在将注意力转向 update() 函数,因为我的项目的位置和尺寸随着时间的推移而变化。
我的第一个实现有效,但它非常天真:
function QuadTree:update(item)
self:remove(item)
return self.root:insert(item)
end
是的,我基本上每次移动时都会删除并重新插入每个项目。
这可行,但我想进一步优化它;毕竟,大多数时候,移动的项目仍然保留在同一个四叉树节点上。
有没有标准的方法来处理这种更新?
如果有帮助,我的代码在这里: https://github。 com/kikito/middleclass-ai/blob/master/QuadTree.lua
我不是在寻找有人为我实现它;指向现有工作实现(即使是其他语言)的指针就足够了。
I've implemented a working QuadTree. It subdivides 2-d space in order to accomodate items, identified by their bounding box (x,y,width,height) on the smallest possible quad (up to a minimum area).
My code is based on this implementation (mine is in Lua instead of C#) : http://www.codeproject.com/KB/recipes/QuadTree.aspx
I've been able to successfully implement insertions and deletions. I've turn now my attention to the update() function, since my items' position and dimensions change over time.
My first implementation works, but it is quite naïve:
function QuadTree:update(item)
self:remove(item)
return self.root:insert(item)
end
Yup, I basically remove and reinsert every item every time they move.
This works, but I'd like to optimize it a bit more; after all, most of the time, moving items still remain on the same quadTree node.
Is there any standard way to deal with this kind of update?
In case it helps, my code is here: https://github.com/kikito/middleclass-ai/blob/master/QuadTree.lua
I'm not looking for someone to implement it for me; pointers to an existing working implementation (even in other languages) would suffice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有一个很好的解决方案(项目->节点索引)来处理更新方法的常见问题,这些问题是由于需要删除旧边界框并插入新边界框而引起的。
插入方法的时间复杂度为 O(ln(N)),但项目停留在同一节点中的更新可以在恒定时间内完成。移动到子节点也可以通过删除对当前保存该项目的节点的搜索来优化,并且移动到相邻节点也可以消除一些搜索,因为每个节点都知道其父节点。
我不懂Lua,所以请将下面的代码视为伪代码。
我不确定是否值得向上和向下扫描。尝试可能很有趣,但只有在非常深的树中才可能值得。
findNode 方法从自身扫描树,通过空间位置查找该项目所属的节点。实现可以选择仅扫描自身节点及其依赖节点:
...或者也使用父节点扫描整个树:
You have a nice solution (an item->node index) for dealing with the usual problem with update methods that arises from the need to remove with the old bounding box and insert with the new bounding box.
The insert method is O(ln(N)) but an update where the item stays in the same node could be accomplished in constant time. Moving to a child node could also be optimized by removing the search down to the node currently holding the item, and moving to adjacent nodes could also eliminate some of this search because each node knows its parent.
I don't know Lua, so please treat the code below as pseudo-code.
I'm not sure that it is worth scanning up the tree as well as down. It might be interesting to try, but it is only likely to be worth it in a very deep tree.
The findNode method scans the tree from self looking for the node that the item belongs to by spatial location. Implementations can choose to scan only the self node and its dependents:
... or to scan the whole tree using parent nodes as well: