Optimization 寻找一个有效的结构来检查哪些圆包含一个点

Optimization 寻找一个有效的结构来检查哪些圆包含一个点,optimization,f#,computational-geometry,delaunay,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 我想知道我的集合中的哪些圆包含新的点。线性搜索很简单。我正在寻找一种结构,可以容纳圆,并返

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

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#中实现这一点,但任何语言的想法都可以

为您提供信息,我希望实施


但是如果我用简单的方法扫描所有的圆来寻找每一个新的点,这将是一个O(N^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(logn)

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

例如,可以创建具有以下属性的四叉树: 1.四叉树的每个单元都包含圆的索引,并与之重叠。 2.每个单元格包含的圆不超过K个(例如10)//可能会断开 3.树的高度以M为界(通常为O(logn))

您可以通过迭代重叠的单元来构造四叉树,如果单元内的圆数超过K,则将该单元细分为四个(如果不超过最大高度)。对于圆内的单元,也应该考虑一些问题,因为它的细分是毫无意义的

当你们找到圆时,你们应该定位四叉树,然后在重叠的圆中迭代,找到那个些包含点的圆

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


我有一篇学士学位论文,在这篇论文中,我采用了四叉树作为最近的线段位置,预期时间为O(logn),我认为类似的方法也可以在这里使用

实际上,你可以搜索外接圆包含新点p的三角形。因此,您的Delaunay三角剖分已经是您所需要的数据结构:首先搜索三角形t,其中包括p(谷歌搜索“Delaunay walk”)。t的外接圆当然包括p。然后从t开始,增长外接圆包括p的三角形的(连通)面积

以一种快速可靠的方式实现它需要大量的工作。除非要创建新库,否则可能需要使用现有库。我的C++方法是FADE2D(1),但还有很多其他的方法,这取决于你的具体需求。p>
[1]

那就来点修改过的四叉树吧。然后你可能会做O(logn)是的,但四叉树是用于不重叠几何对象的点。我不知道如何继续。你至少可以把事情缩小到一个区域上重叠的圆的一些小子集。我在前一段时间致力于解决这个问题,结果证明,如果最大半径与坐标范围相比很小,你(或我)只能打败线性。你能断言关于范围的任何东西吗?我想我可能在寻找这个圆分布将是重叠的圆是delaunay三角剖分的外接圆。这有什么不同吗?@BradGonessurfing为什么不能在delaunay三角测量中定位?我认为在三角剖分中使用三角形,你可以在面的外接圆中找到包含外接圆的面,与你的三角形共享点。@BradGonessurfing我也认为你的情况对答案中的算法来说并不坏。最大细分将在阶数>K的三角剖分顶点处达到。但这没关系,在该顶点附近,除了迭代通过关联圆=)之外,您没有什么更好的方法