寻找一种有效的结构来检查哪些圆圈包围一个点

时间:2013-04-04 08:21:11

标签: optimization f# computational-geometry delaunay

我有一大堆重叠的圆圈,每个圆圈都在一个特定半径的随机位置。

type Circle =
    struct 
      val x: float
      val y: float
      val radius: float
    end

给出类型为

的新点
type Point =
    struct
      val x: float
      val y: float
    end

我想知道我的集合中的哪些圈子包含了新点。线性搜索是微不足道的。我正在寻找一种能够抓住圆圈的结构,并为所呈现的点返回优于O(N)的封闭圆圈。

理想情况下,结构应该快速插入新圆圈并删除圆圈。

我想在F#中实现这一点,但任何语言的想法都可以。

为了您的信息,我希望实施

http://takisword.wordpress.com/2009/08/13/bowyerwatson-algorithm/

但如果我使用天真的方法扫描每个新点的所有圆圈,那将是一个O(N ^ 2)。

3 个答案:

答案 0 :(得分:2)

如果我们假设圆圈分布在区域为1的某个矩形上,并且圆圈的平均面积为a,则具有m级别的四叉树将为您留下一个区域大小1/2^m。这留下了

O(Na/2^m)

作为剩余区域中剩余的预期圆圈数。

但是,我们已经进行了O(log(m))次比较以达到这一点。这使得比较总数为

O(log(m)) + O(N/2^m)

如果log(m)N成比例,则第二项将保持不变。

这表明四叉树可以将事物减少到O(log n)

答案 1 :(得分:2)

四叉树是一种有效的平面搜索结构。你可以用它来保持飞机的细分。

例如,您可以创建具有此类属性的四叉树:  1.四叉树的每个单元都包含圆的索引,与之重叠。  2.每个单元格确实包含不超过K个圆圈(例如10个)//可能会被破坏  树的高度以M(通常为O(log n))

为界

您可以通过迭代重叠的单元构建四叉树,如果单元格内的圆圈数超过K,则将该单元格细分为四个(如果不超过最大高度)。如果圆圈内的单元格也应该考虑某些因素,因为它的细分是没有意义的。

找到圆圈时,您应该对四叉树进行本地化,然后遍历重叠的圆圈并查找包含点的圆圈。

在稀疏圈分布的情况下,搜索将非常有效。

我有一个学士论文,在那里我修改了四叉树,最近的片段位置,预期时间O(log n),我认为类似的方法可以在这里使用

答案 2 :(得分:1)

实际上,您搜索外接圆包含新点p的三角形。因此,您的Delaunay三角剖分已经是您需要的数据结构:首先搜索包含p的三角形t(google for'delaunay walk')。 t的外接层当然包括p。然后从t开始并增长三角形的(连通的)区域,其外接圆包括p。

以快速可靠的方式实施它需要做很多工作。除非您想要创建新库,否则您可能希望使用现有库。我对C ++的方法是Fade2D [1],但也有很多其他方法,这取决于你的具体需求。

[1] http://www.geom.at/fade2d/html/