四叉树学习demo

论坛里关于四叉树的教程有很多,本人也照葫芦画瓢,写了一个demo,加上了我对源码的理解,还望大佬勿喷
话不多说 先上效果


绿色的代表可能会发生碰撞的节点,后续只需要判定目标节点已绿色的进行碰撞检测即可。
源码解读


bounds 描述四叉树的边界,demo已左下角为锚点
maxObjects 每个四叉树容纳的最大数量 默认为10
maxLevels 表示层级,一般设置为4级 通过 maxLevels 和 maxObjects 算出可以容纳的最大数量为 1044*4=640 一般的碰撞场景都可以满足
objects 表示此四叉树的待检测对象
nodes 表示子四叉树节点

此方法对四叉树进行拆分
将父节点的1/4节点重新分割成新的四叉树
coords 代表从第一象限逆时针到第四象限的左下角坐标
maxLevels 和 maxObjects 同父节点相等

判定节点在四叉树占据的区域 参数 node 为四叉树
boundsCenterX ,boundsCenterY 代表四叉树 中心点的区域
图中蓝色矩形区域的锚点在左下角
判定矩形原点(起点)是否在象限的下侧,左侧
再判定矩形框 x轴 y轴的最大值 是不是在象限的右侧 上侧
通过两两满足 就可以排定蓝色矩形框占据的四叉树子节点
依照此判定 矩形框最多可以占据最多四个 四叉树子节点


向四叉树中插入节点
1.首先判定当前四叉树是不是有子节点 如果有 则对子节点进行递归插入,后续的逻辑不进行处理
2.将节点push进 objects 中 并判断是否超过 maxObjects 并且 是否超过 maxLevels
3.2条件满足,则判断下当前数是否有子节点,如没有 则将树进行拆分
4.判定待检测节点所占区域并在此区域内插入。
5.将父节点的 objects清空,因为都被放进了子节点,再在父节点中则无意义。

返回可能会发生碰撞的所有子节点
1.获取目标矩形所占的象限
2.从四叉树的顶部获取 objects (整个四叉树所有的待检测节点数量小于maxObjects后 此值非空,超过 maxObjects 为空(分层之后就放到 nodes 里面了) )
3.nodes 不为空,则递归判定
4.去重
至此源码解析完成
项目地址 源码地址
此demo使用3.6开发

9赞

:+1::+1::+1:

感谢大佬的赞 :smiley_cat:

看到这类话题出现在 Cocos 社区,很开心啊。说明大家又成长了。

1赞

向麒麟子看齐 :clap:

源码地址 源码

mark 赞

你有没有发现如果使用insert方法连续插入大面积的矩形,并且每个矩形与四个子节点重叠,则插入方法就会无限递归

插入之前 会先去判定当前插入的是否有子节点 因为设计的最多就有四层,所以不会无限递归 ,大面积的矩形 会存在很多的节点里面都有他 ,即占据A区域 也占据B区域的子区域内。这个也不会影响后面的retrieve判定 。

good啊

1赞

学习了!晚点有空照着模仿一下!

看完自己搞一个demo,加深一下理解。