我有 n 行和 m 個圓圈。
我有一個 [n,2] numpy 線起點陣列:
[x1_1,y1_1],
[x1_2,y1_2],
...
[x1_n,y1_n]
還有一個 [n,2] numpy 行端點陣列:
[x2_1,y2_1],
[x2_2,y2_2],
...
[x2_n,y2_n]
還有一個 [m,2] numpy 圓心陣列:
[cx_1,cy_1],
...
[cx_m,cy_m]
還有一個 [m,1] numpy 圓半徑陣列:
[cr_1...cr_m]
我想有效地獲得一個 [n,m] numpy 陣列,其中如果線 i 與圓 j 相交,陣列 [i,j] 為真。
一般來說,我會將歸一化的垂直向量與每條線相乘,然后將其與每個 (xi,yi) - (cx_j,cy_y) 相乘并詢問它是否小于 cr_i; 但我還必須檢查該隱含點是否在線,如果沒有,則單獨檢查每一端。我想知道是否有更優雅的解決方案。
uj5u.com熱心網友回復:
好的,假設有這些形狀
start = (np.random.random((3,2))-.5)*5
end = (np.random.random((3,2))-.5)*5
center = (np.random.random((4,2))-.5)*5
radius = np.random.random((4,1))*3

對于每個中心,我們可以通過以下方式計算與三條線的距離:
D = np.array([
np.linalg.norm(np.cross(end-start, start-c).reshape(-1,1),axis=1)/np.linalg.norm((end-start).reshape(-1,2), axis=1)
for c in center
]).T
D[i,j] 將是線 i(以行為單位)和中心 j(以 clumns 為單位)之間的距離。現在我們可以簡單地將這個距離與半徑距離進行比較:
I = (d<radius.repeat(len(start), axis=1).T)
I是與D同形的矩陣;如果直線 i 和中心 j 之間的距離小于半徑 j(因此如果直線 i 與圓 j 相交),則 I[i,j] 為 True,否則為 False。
我知道它不是很優雅,但我希望它有用。
uj5u.com熱心網友回復:
我想不出比問題中概述的演算法更簡單的演算法。就實作而言,使用shapely.
首先,讓我們生成并繪制一些樣本資料:
from itertools import product
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import matplotlib.colors as mcolors
from shapely.geometry import LineString, Point, MultiLineString
import numpy as np
import pandas as pd
# generate data
rng = np.random.default_rng(123)
start = (rng.random((3, 2)) - .5) * 5
end = (rng.random((3, 2)) - .5) * 5
center = (rng.random((4, 2)) - .5) * 5
radius = rng.random((4, 1)) * 3
# plot lines and circles
fig, ax = plt.subplots()
fig.set_size_inches(8, 8)
ax.set_aspect('equal')
colors = list(mcolors.TABLEAU_COLORS.keys())
for i, ends in enumerate(zip(start, end)):
ax.plot(*zip(*ends), label=f"line {i}")
for i, (c, r) in enumerate(zip(center, radius)):
ax.add_patch(Circle(c, r, fill=False, ec=colors[i], label=f"circle {i}"))
plt.legend()
plt.show()
這給出了:

接下來,計算交點陣列,行對應于線,列對應于圓:
lines = [LineString(ends) for ends in list(zip(start, end))]
circles = [Point(c).buffer(r).boundary for c, r in zip(center, radius)]
out = np.empty((len(lines), len(circles)), dtype=bool)
for i, (l, c) in enumerate(product(lines, circles)):
out[np.unravel_index(i, out.shape)] = l.intersects(c)
#convert to a dataframe for better display
df = pd.DataFrame(out)
df.index.name = 'lines'
df.columns.name = 'circles'
print(df)
結果:
circles 0 1 2 3
lines
0 True False True True
1 False False False True
2 False False False False
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/420314.html
標籤:
