【发布时间】:2018-03-13 20:10:42
【问题描述】:
给定一个起点(82, 186) 和一组周围点[(105, 186), (95, 157), (81, 159), (64, 173), (52, 188), (127, 195)],我如何确定适合这些点的最大圆?
注意:中心不必是起点
cX, cY = (82, 186)
points = [(105, 186), (95, 157), (81, 159), (64, 173), (52, 188), (127, 195)]
def closest_node(node, nodes):
nodes = np.asarray(nodes)
deltas = nodes - node
dist = np.linalg.norm(deltas, axis=1)
min_idx = np.argmin(dist)
return nodes[min_idx], dist[min_idx], deltas[min_idx][1]/deltas[min_idx][0] # point, distance, slope
(pX, pY), d, m = closest_node((cX, cY), points)
cv2.circle(img, (cX, cY), int(d), (255, 0, 255), 1) # circle with center C, touching point P
# learning rate
a = 0.2
# sign for direction
sX = 1 if cX - pX > 0 else -1
sY = 1 if cY - pY > 0 else -1
dx = (d * a) * np.sqrt(1 / (1 + m**2))
# New center
nX = cX + sX * dx
nY = cY + sY * m * dx
cv2.circle(img, (int(nX), int(nY)), int(d + (d * a)), [0, 0, 0], 1)
所以我尝试迭代地处理第二点(然后是第三点),但我认为如果有一个矢量化方法会更好。我该怎么做?
编辑:使用 Voronoi 的解决方案
from scipy.spatial import Voronoi
points = np.array(points)
if len(points) >= 4:
vor = Voronoi(points)
max_d = 0
max_v = None
for v in vor.vertices:
cv2.circle(img, (int(v[0]), int(v[1])), 3, [200, 200, 0], 1)
_, d, _ = closest_node(v, points)
if d > max_d:
max_d = d
max_v = v
cv2.circle(img, (int(max_v[0]), int(max_v[1])), int(max_d), [0, 0, 0], 1)
【问题讨论】:
-
如果不是中心,是的起点是什么?只是另一点?如果是这样,为什么它不在列表中?如果它不是中心,你为什么称它为
cx和cy? -
呃,你的意思是找到包含所有点的最小圆吗?因为否则你总能找到一个远离所有点的更大的圆圈......
-
@Julien 我刚刚尝试了你的答案......不错,但我正在寻找如下建议的最大内切圆,而不是最小的封闭圆:)
-
这是不正确的定义,除非您明确指定所需的解决方案如何绑定到起点。
-
它没有绑定到起点,但我只是碰巧知道起点会在包含最大圆圈的区域内
标签: python numpy geometry linear-algebra computational-geometry