存储要通过x,y坐标定位的对象
时间:2020-03-06 14:42:42 来源:igfitidea点击:
我正在尝试确定一种存储一组对象的快速方法,每个对象都有一个x和y坐标值,以便可以快速检索某个矩形或者圆形内的所有对象。
对于小型对象集(约100个),仅将它们存储在列表中并对其进行迭代的幼稚方法相对较快。但是,对于更大的群体,这预计会很慢。
我也尝试使用以下代码将它们存储在一对TreeMap中,一个按x坐标排序,一个按y坐标排序:
xSubset = objectsByX.subSet( minX, maxX ); ySubset = objectsByY.subSet( minY, maxY ); result.addAll( xSubset ); result.retainAll( ySubset );
这也可行,并且对于较大的对象集更快,但是仍然比我想要的慢。
部分问题还在于这些对象会四处移动,并且需要重新插入该存储中,这意味着将它们从树中删除并重新添加到树/列表中。
我忍不住认为必须有更好的解决方案。
我正在用Java实现此功能,如果有什么不同的话,尽管我希望任何解决方案都可以采用有用的模式/算法的形式。
解决方案
四叉树是通常用于此的结构。
看看Kd-Trees。
通用术语是空间索引。我想我们应该根据现有的实现方式进行选择。
四叉树似乎可以解决我所问的具体问题。 Kd-Tree是一种更通用的形式,适用于任意数量的维度,而不仅仅是两个。
如果要存储的对象具有边界矩形,而不仅仅是一个简单的点,则R-Trees也可能很有用。
这些类型的结构的总称是空间索引。
有一个Java实现的Quadtree和R-Tree。
我们可以将所有x线放置在地图中,将y线放置在另一个地图中,并使地图值指向对象。
TreeMap<Integer, TreeMap<Integer, Point>> xMap = new TreeMap<Integer, TreeMap<Integer, Point>>(); for (int x = 1; x < 100; x += 2) for (int y = 0; y < 100; y += 2) { Point p = new Point(x, y); TreeMap<Integer, Point> tempx = xMap.get(x); if (tempx == null) { tempx = new TreeMap<Integer, Point>(); xMap.put(x, tempx); } tempx.put(y, p); } SortedMap<Integer, TreeMap<Integer, Point>> tempq = xMap.subMap(5, 8); Collection<Point> result = new HashSet<Point>(); for (TreeMap<Integer, Point> smaller : tempq.values()) { SortedMap<Integer, Point> smallerYet = smaller.subMap(6, 12); result.addAll(smallerYet.values()); } for (Point q : result) { System.out.println(q); } }
C语言中的简单QuadTree实现(易于转换为Java)
http://www.codeproject.com/KB/recipes/QuadTree.aspx