古いバウンディングボックスで削除し、新しいバウンディングボックスで挿入する必要から生じる、更新メソッドの通常の問題に対処するための優れたソリューション(アイテム->ノードインデックス)があります。
挿入メソッドはO(ln(N))ですが、アイテムが同じノードにとどまる更新は、一定時間で実行できます。子ノードへの移動は、現在アイテムを保持しているノードまで検索を削除することによって最適化することもできます。また、隣接するノードに移動すると、各ノードがその親を知っているため、この検索の一部を削除できます。
Luaがわからないので、以下のコードを擬似コードとして扱ってください。
function QuadTree:update(item)
oldNode = root.assignments[item]
newNode = oldNode:findNode(item)
if (oldNode ~= newNode) then
-- if findNode only searches down the tree newNode will be nil if
-- the item needs to move to/under an adjacent node. Otherwise the
-- next three lines are not needed
if (newNode == nil) then
newNode = root:findNode(item)
end
oldNode:remove(item)
newNode = newNode:insert(item)
end
return newNode
end
ツリーを上だけでなく下にもスキャンする価値があるかどうかはわかりません。試してみるのは面白いかもしれませんが、非常に深い木でそれだけの価値がある可能性があります。
findNodeメソッドは、自己からツリーをスキャンして、アイテムが属するノードを空間的な場所で探します。実装は、自己ノードとその依存関係のみをスキャンすることを選択できます。
-- Returns the node that the item belongs to by spatial location.
-- The tree can already contain the item. The item might be indexed using
-- an old geometry.
-- This method does not create child nodes.
function QuadTree:findNode(item)
local x,y,w,h = item:getBoundingBox()
if( not _contained(x,y,w,h , self:getBoundingBox()) ) then
-- Attempted to insert an item on a QuadTree that does not contain it;
-- just return
return nil
end
for _,node in ipairs(self.nodes) do
if(node:findNode(item) ~= nil) then return node end
end
return self
end
...または、親ノードを使用してツリー全体をスキャンする場合も同様です。
-- Returns the node that the item belongs to by spatial location.
-- The tree can already contain the item. The item might be indexed using
-- an old geometry.
-- This method does not create child nodes.
function QuadTree:findNode(item)
local x,y,w,h = item:getBoundingBox()
if( not _contained(x,y,w,h , self:getBoundingBox()) ) then
-- Attempted to insert an item on a QuadTree that does not contain it;
-- scan the parent
if (parent == nil) then return nil end
return parent:findNode(item)
end
for _,node in ipairs(self.nodes) do
if(node:findNode(item) ~= nil) then return node end
end
return self
end