[英]Find the intersection points of all circles
給定一組 2D 坐標和每個坐標的半徑,如何有效地找到一組圓中至少有 2 個圓相交的所有點?
我了解兩個圓最多相交 2 個點,因此可以通過兩個圓之間的成對比較並循環遍歷整個數據集來完成,但是當實際數據集有 10000 個圓時,進行所有成對比較的計算成本會很高。
下面是生成測試數據的示例代碼。
library("plotrix")
set.seed(1995)
XCoordinate = sample(x = 1:100,size = 20)
set.seed(2000)
YCoordinate = sample(x = 1:100,size = 20)
set.seed(1997)
Radius = sample(x = 1:50,size = 20)
## Create DataFrame
TestData = data.frame(XCoordinate = XCoordinate,YCoordinate = YCoordinate,
Radius = Radius )
## Plot Circle
plot(TestData$XCoordinate, TestData$YCoordinate,
type="n", xlab="", ylab="" , main="Test draw.circle")
for(Row in 1:nrow(TestData)){
PlotCircle(TestData$XCoordinate[Row],
TestData$YCoordinate[Row],
TestData$Radius[Row])
}
我正在嘗試找到附件中所有標記為黑色的點。
您可能會得到很多誤報候選,但除非圓圈幾乎彼此重疊,否則我們可以通過計算圓圈的邊界框並運行線掃描來顯着減少對檢查的數量。 相交圓意味着邊界框相交,但反之則不然。
實施起來可能更復雜,但可能比 גלעד ברקן 的解決方案更具選擇性:
構建一個R-Tree ,組織圓心並向每個節點添加一個附加屬性maxRadius
,該屬性包含該節點中包含的任何圓的最大半徑
對於每個圓c
,找到在 R 樹上執行范圍搜索的候選圓。 當minDist(c, p) > c.radius + p.maxRadius
時丟棄節點p
在 2D 中構建 R 樹通常是 O(n log n),對於中等范圍(半徑),范圍搜索被認為是 O(log n)。 在平均情況下,這使得總共O(n log n) 。
我已經在 C++ 中實現了圓相交的掃描線算法:github.com/malyasova/intersect_circles
它的工作原理類似於線段相交算法,只是將每個圓的上下圓弧插入狀態而不是線段。 它在 O((n+k)log n) 時間內工作,其中 n 是圓的數量,k 是交叉點的數量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.