我正在构建一个与googleplacesapi交互的程序,以识别美国郡内所有给定类型的机构。谷歌接受半径形式的搜索,所以为了覆盖整个区域,我把搜索半径从一个半径到另一个半径依次建立起来。但是,这个算法创建了很多重叠的圆,我想过滤掉。所以:
给定一个圆的列表,每个圆的中心和半径,我如何判断一个圆是否完全被其他圆的组合所覆盖?你知道吗
我已经知道一个圆是否被另一个圆包围了——我的问题是,很多圆都被其他几个圆的组合包围了。你知道吗
有人问我现有的代码-代码我目前有测试,如果一个圈是完全重叠的另一个圈-不是他们的组合。但这就是我所拥有的。你可以看到,我正在通过排除它是否与其他20个圆重叠来近似当前的问题,在这一点上,它可能包含:
def radiusIsInsidePreviousQuery(self, testQuery):
newSearchCoordinates = (testQuery['center']['lat'], testQuery['center']['lng'])
alreadyBeenSearched = False
numberOfIntersectingCircles = 0
for queryNumber in self.results.keys():
previousQuery = self.results[queryNumber]
previousSearchCoordinates = (previousQuery['center']['lat'],
previousQuery['center']['lng'])
centroidDistance = VincentyDistance(newSearchCoordinates,
previousSearchCoordinates)
centroidDistanceMeters = centroidDistance.meters
newQueryRadius = testQuery['radius']
fullSearchDistance = centroidDistanceMeters + newQueryRadius
#If the full search distance (the sum of the distance between
#the two searches' centroids and the new search's radius) is less
#than the previous search's radius, then the new search is encompassed
#entirely by the old search.
previousQueryRadius = previousQuery['radius']
if fullSearchDistance <= previousQueryRadius:
print "Search area encompassed"
alreadyBeenSearched = True
elif centroidDistanceMeters < newQueryRadius + previousQueryRadius:
numberOfIntersectingCircles += 1
elif self.queriesAreEqual(testQuery, previousQuery):
print "found duplicate"
alreadyBeenSearched = True
#If it intersects with 20 other circles, it's not doing any more good.
if numberOfIntersectingCircles > 20:
alreadyBeenSearched = True
return alreadyBeenSearched
让我们考虑要测试的圆A
我不知道你的计算需要多精确,但假设用100点表示A的周长就足够了。你知道吗
导入数学
您可以将此作为磁盘联合问题来解决。这个问题与Alpha shapes理论有关,可以通过构造一个weighted (additive) Voronoi diagram来解决,这个
O(n Log(n))
可以在n
磁盘的O(n Log(n))
时间内执行。你知道吗可以按如下方式使用此构造:从列表中计算磁盘的并集。然后将单个磁盘添加到此联合。如果没有变化,则包含单个磁盘。你知道吗
您将不得不使用一个高级软件包,比如CGAL,因为算法远不简单。你知道吗
如果你可以用一个近似的解决方案,并着眼于易于编程,只需在一个空白的图像中画一个合适的分辨率磁盘。然后检查单个磁盘的绘制是否达到新像素。你知道吗
这种方法成本高昂,因为您需要处理的像素数等于磁盘的总面积。你知道吗
混合解决方案也可以作为难度和效率之间的折衷方案。你知道吗
选择垂直分辨率并用等距水平线交叉填充平面。它们将沿着一条线段与每个圆盘相交。为每个水平磁盘保留一个段列表,并在添加新磁盘时执行段的并集是一件容易的事情。(通过对重叠进行排序和计数,
n
段的并集很容易实现。)相关问题 更多 >
编程相关推荐