Home 十字链表AOI
Post
Cancel

十字链表AOI

十字链表

根据2d地图坐标系将其分成x轴和y轴两个双向链表,如果是3d地图,则需要多维护一条代表高度的双向链表。对象按照坐标值从小到大相应的排列在相应的坐标轴上面。

  • crosslist.png

数据结构
  • 对象的视野半径必须固定最大视野范围,例如坐标系+/-3,在对象进入,移动,离开时作为遍历xy链表的范围。判断是否在视野范围时,需要分别遍历x、y两轴,再求两轴的交集。
  • aoi对象只存储entityId和aoi,位置数据,只做视野计算和回调通知,由业务层的对象entity保存兴趣列表和被关注列表。
    • 兴趣列表:进入我AOI范围的实体,我感兴趣的对象集合。
    • 被关注列表:我进入了谁的AOI范围,关注我的对象集合。

对象进入

新增的对象需要根据x坐标和y坐标,遍历对应的链表并找到合适的位置插入。

  • enter.png

对象移动

对象移动后若只改变x坐标,则只调整x轴链表,若只改变y轴坐标,则只调整y轴链表。根据移动后的坐标找到合适的位置并调整链表节点指针的指向。

  • move.png

对象离开

对象离开则将链表中的对应节点断开即可。

  • leave.png

优化
  • 每次新增对象,都需要遍历对应的链表找到对应的位置插入,此处可以通过快慢指针加快遍历,快指针每次移动n个位置,直到大于新增对象的坐标值,则慢指针开始往快指针位置逐个移动,直到找到合适的位置。否则插入到链表的尾部。
  • 只用一条x轴链表,遍历x轴,判断每个实体是否在视野内更高效。可以使用跳跃表替换。

应用场景
  • 十字链表不适合对象频繁进出场景的情况。因为每次对象的进入都需要往x轴和y轴双向链表中找到合适的位置插入。
  • 十字链表每次对象的小幅度移动,只需要关注x轴和y轴更精准的邻居是否在视野内,没有多余的运算。
This post is licensed under CC BY 4.0 by the author.