选择矩阵中距离另一个点30米的所有点

时间:2010-05-11 22:24:08

标签: c++ database data-structures matlab matrix

因此,如果你看看我的其他帖子,我正在构建一个可以在森林中收集数据并将其粘贴在地图上的机器人也就不足为奇了。我们的算法可以检测树中心和树干直径,并且可以将它们粘贴在笛卡尔XY平面上。

我们计划使用某些“关键”树作为本地化机器人的自然地标,使用三角测量和三边测量等方法,但只使用Matlab进行编程并保持数据的直接和高效变得困难。

是否存在一种用于设置点阵或点阵矩阵的技术?假设我在1公里(1000米)内存放了1000棵树,有没有办法说,只选择我当前位置半径30米范围内的点并只使用那些?

我只是使用GIS,但我在Matlab中这样做,我不知道任何用于Matlab的GIS插件。

我忘了提一下,这段代码正在上线,这意味着它正在用于实时执行的机器人。我不知道,当地图增长到几英里时,使用不同的数据结构将有助于或者如果计算到随机点的每个距离都是空间数据库将要做的事情。

我正在考虑将树的数组镜像为两个数组,一个按X排序,另一个按Y排序。然后冒泡排序以确定其中的30米范围。我对两个数组,X和Y做同样的事情,然后有第三个交叉链接表,它将选择各个值。但我不知道,有什么叫做,如何编程,我相信有人已经有了,所以我不想重新发明轮子。

Cartesian Plane
GIS

6 个答案:

答案 0 :(得分:6)

您正在寻找像quadtreekd-tree这样的空间数据库。我发现了两个kd-tree实现herehere,但没有找到任何针对Matlab的四叉树实现。

答案 1 :(得分:3)

计算所有距离和扫描的简单解决方案似乎几乎是瞬间完成的:

lim = 1;
num_trees = 1000;

trees = randn(num_trees,2); %# list of trees as Nx2 matrix
cur = randn(1,2); %# current point as 1x2 vector
dists = hypot(trees(:,1) - cur(1), trees(:,2) - cur(2)); %# distance from all trees to current point
nearby = tree_ary((dists <= lim),:); %# find the nearby trees, pull them from the original matrix

在1.2 GHz机器上,我可以处理100万棵树(1个MTree?)&lt; 0.4秒。

您是否直接在机器人上运行Matlab代码?你在使用Real-Time Workshop吗?如果您需要将其翻译为C,则可以将hypot替换为sqr(trees[i].x - pos.x) + sqr(trees[i].y - pos.y),并将限制检查替换为< lim^2。如果你真的只需要处理1 KTree,我不知道实现更复杂的数据结构是值得的。

答案 2 :(得分:2)

您可以使用CART2POL将笛卡尔坐标转换为极坐标。然后选择一定范围内的点将是前进的。

[THETA,RHO] = cart2pol(X-X0,Y-Y0);
selected =  RHO < 30;

其中X0,Y0是当前位置的坐标。

答案 3 :(得分:1)

我的猜测是树木大致均匀地分布在森林中。如果是这种情况,只需将30x30(或15x15)网格块作为哈希密钥用于closed hash table。查找与搜索圈相交的所有块的键,并检查从该键开始的所有哈希条目,直到其中一个被标记为其“桶”中的最后一个。

0---------10---------20---------30--------40---------50----- address # line
(0,0)     (0,30)     (0,60)     (30,0)    (30,30)    (30,60) hash key values

(1,3) (10,15) (3,46) (24,9.) (23,65.) (15,55.) tree coordinates + "." flag

例如,要获取(0,0)...(30,30)中的树,将(0,0)映射到地址0并读取条目(1,3),(10,15) ),拒绝(3,46)因为它超出范围,读取(24,9)并停止,因为它被标记为该扇区中的最后一棵树。

要在(0,60)...(30,90)中获取树,请将地图(0,60)映射到地址20.跳过(24,9),读取(23,65),然后停止,因为它是最后一个。< / p>

这将是非常有效的内存,因为它避免了存储指针,否则这些指针相对于实际数据而言会相当大。然而,封闭散列需要留下一些空白空间。

图示不是“按比例缩放”,因为实际上在散列键标记之间存在多个条目的空间。所以你不应该跳过任何条目,除非在本地前面的扇区中有比平均值更多的树。

这确实使用了哈希冲突,因此它不像哈希函数那样随机。 (并非每个条目都对应一个不同的哈希值。)但是,由于森林的密集区域通常是相邻的,您应该将扇区的映射随机化为“桶”,这样一个给定的密集扇区有望溢出到一个密度较小的区域,或下一个,或下一个。

此外,存在空扇区和终止迭代的问题。您可以在每个扇区中插入一个虚拟树,将其标记为空,或者其他一些简单的黑客。

很抱歉很长的解释。这种事情比文档更容易实现。但性能和足迹可以很好。

答案 4 :(得分:0)

使用某种空间分区的数据结构。一个简单的解决方案是简单地创建一个包含30米x 30米区域内所有对象的二维列表。最糟糕的情况是,您只需要与其中四个列表中的对象进行比较。

也可以使用大量更复杂(也可能是有益的)解决方案 - 像双树这样的东西实现起来要复杂一些(但不是很多),但可以获得更优的性能(特别是在密度较高的情况下)对象差异很大。)

答案 5 :(得分:0)

您可以在matlab中查看voronoi图表支持:

http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoi.html

如果你将voronoi多边形基于关键树,并将相邻树聚类成那些多边形,那么将通过接近度划分搜索空间(找到给定非关键点的封闭多边形很快),但最终你我将通过毕达哥拉斯或者三角形来计算非关键距离的计算关键并进行比较。

对于几千点(树木),如果你有一个合理的处理器,蛮力可能足够快。计算树中每个其他树的距离,然后选择30'内的树。这与所有树在同一个voronoi多边形中相同。

自从我在地理信息系统工作几年后,我发现以下内容非常有用:'计算几何在C'约瑟夫O Rourke,ISBN 0-521-44592-2平装本。