我有一大堆重叠的圆圈,每个圆圈都在一个特定半径的随机位置。
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)。
答案 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],但也有很多其他方法,这取决于你的具体需求。