lua-四叉树(cocos2d-x-lua)
--构建四叉树 local quadTree = class("quadTree") function quadTree:ctor(rect,max_objects,max_level,level) self._rect = rect self._max_objects = max_objects or 8 self._max_level = max_level or 4 self._level = level self._trees = {} self._objects = {} end --分裂树 function quadTree:splitTree() local width = self._rect.width/2 local height = self._rect.height/2 local x = self._rect.x + width local y = self._rect.y + height local level = self._level + 1 self._trees[1] = quadTree.new({x = x + width,y = y + height,width = width,height = height},self._max_objects,self._max_level,level) self._trees[2] = quadTree.new({x = x,y = y + height,width = width,height = height},self._max_objects,self._max_level,level) self._trees[3] = quadTree.new({x = x,y = y,width = width,height = height},self._max_objects,self._max_level,level) self._trees[4] = quadTree.new({x = x + width ,y = y,width = width,height = height},self._max_objects,self._max_level,level) end -- --- y—————————————————h --- | | | --- | 2 | 1 | --- | | | --- |———————————————— --- | | | --- | 3 | 4 | --- | | | --- x—————————————————w --- --所属子树index function quadTree:getTreeIndexs(rect) local treeIndexs = {} local c_x = self._rect.x + self._rect.width/2 local c_y = self._rect.y + self._rect.height/2 local is_left = rect.x < c_x local is_top = rect.y > c_y local end_left = rect.x + rect.width < c_x local end_top = rect.y + rect.height > c_y --1 if (is_top and not end_left) or (not is_left and end_top) then table.insert( treeIndexs,1) end --2 if (is_top and end_left) or (is_left and end_top ) then table.insert( treeIndexs,2) end --3 if (not is_top and end_left) or (is_left and not end_top) then table.insert( treeIndexs,3) end --4 if (not is_top and not end_left) or (not is_left and not end_top) then table.insert( treeIndexs,4) end return treeIndexs end --插入 function quadTree:insert(rect) if self._trees and next(self._trees) then local treeIndexs = self:getTreeIndexs(rect) for k,index in ipairs(treeIndexs) do self._trees[index]:insert(rect) end return end table.insert( self._objects,rect) if #self._objects > self._max_objects and self._level <= self._max_level then if not (self._trees and next(self._trees)) then self:splitTree() end for i,k in ipairs(self._objects) do local k_indexs = self:getTreeIndexs(k) for _,index in ipairs(k_indexs) do self._trees[index]:insert(k) end end self._objects = {} end end -- function quadTree:hashCode(_object) local tag = _object.x..'_'.._object.y.."_".._object.width.."_".._object.height return tag end --列表相加 并且去重 function quadTree:tableAdd(table1,table2) local hashTags = {} local newTables = table1 or {} for _,value in ipairs(newTables) do hashTags[self:hashCode(value)] = true end if table2 and next(table2) then for _,value in ipairs(table2) do local hashtag = self:hashCode(value) if not hashTags[hashtag] then hashTags[hashtag] = true table.insert( newTables,value) end end end return newTables end --取回同一组object function quadTree:retrieve(rect) local newObjects = self._objects if self._trees and next(self._trees) then local treeIndexs = self:getTreeIndexs(rect) for _,index in ipairs(treeIndexs) do newObjects = self:tableAdd(newObjects,self._trees[index]:retrieve(rect)) end end return newObjects end function quadTree:clearTree() self._objects = {} for _,tree in pairs(self._trees) do tree:clearTree() end end function quadTree:dumpTree() sys.log("[quadTree]-level="..self._level) if self._objects and next(self._objects) then sys.log("[quadTree]-objects:") sys.dump(self._objects) end for index,child_tree in pairs(self._trees) do sys.log("[quadTree]-index="..index) child_tree:dumpTree() end end return quadTree
yy_room