问题 什么是用于在Java中存储和搜索2d空间坐标的良好数据结构


我目前正在为游戏编写一个插件,其中一个功能包括设置由2个二维坐标(矩形的左上角和右下角区域)定义的区域的能力。然后存储这些区域,并且将具有与每个区域相关联的各种其他数据。当玩家在世界各地移动时,我需要确定他何时只从玩家的坐标进入这些区域中的一个,并且这样做的方法必须是有效的,因为这最终会被称为每秒数百次。

是否有任何数据结构可以有效地支持这种搜索,如果是这样,我在哪里可以找到它的文档,找到要使用的java实现,或者如果需要,自己实现它?

我还想注意,我发现了一些似乎只支持批量加载的树结构,但我必须能够实时添加和删除此结构中的值。


1624
2018-05-30 18:33


起源

另见这个 回答。 - trashgod
多少个矩形?矩形经常变化吗?添加/删除矩形的任何性能要求? - meriton
@meriton - 矩形不会被更改,只会添加和删除,并且因为它在服务器上运行,所以它需要每秒至少处理几次插入而不会损害服务器的性能,尽管平均来说它可能只被调用每分钟一次。 - Sethcran
@trashgod - 我需要能够有效地搜索空间,而不仅仅是确定是否包含形状,这已经是微不足道的了,但是要详尽地搜索数千个或更多形状的列表以查看是否包含它不是高效。 - Sethcran
你能比千人以上更具体吗? 10000? 100000?百万? - meriton


答案:


确定空间部分碰撞的良好数据结构是 四叉树 数据结构。四叉树根据给定区域中的元素数量递归地划分空格。因此,如果坐标在对数时间内位于区域内,则可以进行搜索。

编辑:我找到了一个实现 这里 但没有给出许可证信息。


11
2018-05-30 18:36



绝对是迄今为止提出的最佳解决方案。 - Sethcran
像这样的答案提醒我为什么我喜欢这个网站 - 我每天都在不断学习新东西! - Hovercraft Full Of Eels
但问题不在于某一点是否在特定区域内,而是哪些区域新的或不再包含该点。我没有看到四叉树如何帮助它? - meriton
@meriton - “我需要确定他何时只从玩家的坐标进入其中一个区域” - 我可以使用树来确定玩家何时进入某个区域,并结合位置缓存,它将完全做到我在寻找。 - Sethcran
有一个 麻省理工学院在GitHub上许可实施QuadTree。 - chrisjleu


在一维情况下,合适的数据结构是 区间树

要解决二维强制转换,您可以使用区间树快速查找包含至少一个维度中的点的矩形,并检查每个矩形的第二个维度(可能已经足够快),或者使用维基百科文章简要概述了许多方面的概括(尽管我必须承认我不理解第一次阅读的概括)。

假设玩家移动缓慢(即区域进入或离开事件的数量与区域数量相比较小),以下方法可能更有效:保留x坐标的搜索树,其中矩形开始或结束,以及a y坐标的类似树。如果玩家进入或离开某个区域,他必须越过边界点的x或y坐标。也就是说,您将在x搜索树上对范围[old_x,new_x]执行范围查询,并检查每个矩形。对y方向执行相同操作(不报告重复项)。


1
2018-05-30 19:55





要实现坐标,您可以在实现您正在寻找的功能的类中使用Point2D:

http://download.oracle.com/javase/6/docs/api/java/awt/geom/Point2D.html


0
2018-05-30 18:36