- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 scipy.spatial.Voronoi
计算 Voronoi 图每个区域的确切边界,前提是所有点都在预定义的多边形内。例如,使用此 documentation 中的示例.
如果我需要计算具有相同点但位于具有以下边界的矩形内的 Voroni 怎么办
global_boundaries = np.array([[-2, -2], [4, -2], [4, 4], [-2, 4], [-2, -2]])
我需要像那样计算每个 Voronoi 区域的精确边界吗?
voronoi_region_1_boundaries = [[-2, -2], [0.5, -2], [0.5, 0.5], [-2, 0-5], [-2, -2]]
voronoi_region_2_boundaries = [[-2, 1.5], [0.5, 1.5], [0.5, 4], [-2, 4], [-2, 1.5]]
voronoi_region_3_boundaries = [[-2, 0.5], [0.5, 0.5], [0.5, 1.5], [-2, 1.5], [-2, 0.5]]
以此类推所有 9 个区域,而不是
vor.regions
[[], [-1, 0], [-1, 1], [1, -1, 0], [3, -1, 2], [-1, 3], [-1, 2], [3, 2, 0, 1], [2, -1, 0], [3, -1, 1]]
如何计算无限脊的缺失端点?
我已尝试修改此代码 http://nbviewer.ipython.org/gist/pv/8037100
与此问题相关Colorize Voronoi Diagram
但它仅适用于圆形边界。我修改了它,考虑了一个半径,使我的区域完全在圆内,然后计算连接点和圆周的线与边界之间的交点。它有效,但仅适用于第一点,之后我得到“GEOMETRYCOLLECTION EMPTY”结果。
direction = np.sign(np.dot(midpoint - center, n)) * n
super_far_point = vor.vertices[v2] + direction * radius
line_0 = LineString([midpoint, super_far_point])
for i in range(0, len(map_boundaries)-1):
i += 1
line_i = LineString([(map_boundaries[i-1]), (map_boundaries[i])])
if line_0.intersection(line_i) != 0:
far_point = line_0.intersection(line_i)
new_region.append(len(new_vertices))
new_vertices.append(far_point.tolist())
有没有人解决过类似的问题?
有人能帮忙吗?
最佳答案
我建议采用以下两步法:
首先,为每个 Voronoi 区域制作一个凸多边形。在无限区域的情况下,通过将无限远的点分成两个足够远的点,由一条边连接起来。 (“足够远”意味着额外的边缘完全通过边界多边形之外。)
使用 shapely 的 intersection
将步骤 (1) 中的每个多边形与边界多边形相交方法。
这种方法相对于 Ophir Cami's answer 的好处是它适用于非凸边界多边形,代码更简单一些。
让我们从 Ophir Cami's answer 中的点的 Voronoi 图开始.无限脊由 scipy.spatial.voronoi_plot_2d
显示为虚线:
然后,我们为每个 Voronoi 区域构造一个凸多边形。这对于有限区域来说很容易,但我们必须拉远很远才能看到无限 Voronoi 区域会发生什么。对应于这些区域的多边形有一个额外的边缘,它距离足够远,完全位于边界多边形之外:
现在我们可以将每个 Voronoi 区域的多边形与边界多边形相交:
在这种情况下,所有 Voronoi 多边形都与边界多边形有非空交集,但在一般情况下,其中一些可能会消失。
第一步是生成对应于 Voronoi 区域的多边形。与 Ophir Cami 一样,我从 scipy.spatial.voronoi_plot_2d
的实现中得出这个.
from collections import defaultdict
from shapely.geometry import Polygon
def voronoi_polygons(voronoi, diameter):
"""Generate shapely.geometry.Polygon objects corresponding to the
regions of a scipy.spatial.Voronoi object, in the order of the
input points. The polygons for the infinite regions are large
enough that all points within a distance 'diameter' of a Voronoi
vertex are contained in one of the infinite polygons.
"""
centroid = voronoi.points.mean(axis=0)
# Mapping from (input point index, Voronoi point index) to list of
# unit vectors in the directions of the infinite ridges starting
# at the Voronoi point and neighbouring the input point.
ridge_direction = defaultdict(list)
for (p, q), rv in zip(voronoi.ridge_points, voronoi.ridge_vertices):
u, v = sorted(rv)
if u == -1:
# Infinite ridge starting at ridge point with index v,
# equidistant from input points with indexes p and q.
t = voronoi.points[q] - voronoi.points[p] # tangent
n = np.array([-t[1], t[0]]) / np.linalg.norm(t) # normal
midpoint = voronoi.points[[p, q]].mean(axis=0)
direction = np.sign(np.dot(midpoint - centroid, n)) * n
ridge_direction[p, v].append(direction)
ridge_direction[q, v].append(direction)
for i, r in enumerate(voronoi.point_region):
region = voronoi.regions[r]
if -1 not in region:
# Finite region.
yield Polygon(voronoi.vertices[region])
continue
# Infinite region.
inf = region.index(-1) # Index of vertex at infinity.
j = region[(inf - 1) % len(region)] # Index of previous vertex.
k = region[(inf + 1) % len(region)] # Index of next vertex.
if j == k:
# Region has one Voronoi vertex with two ridges.
dir_j, dir_k = ridge_direction[i, j]
else:
# Region has two Voronoi vertices, each with one ridge.
dir_j, = ridge_direction[i, j]
dir_k, = ridge_direction[i, k]
# Length of ridges needed for the extra edge to lie at least
# 'diameter' away from all Voronoi vertices.
length = 2 * diameter / np.linalg.norm(dir_j + dir_k)
# Polygon consists of finite part plus an extra edge.
finite_part = voronoi.vertices[region[inf + 1:] + region[:inf]]
extra_edge = [voronoi.vertices[j] + dir_j * length,
voronoi.vertices[k] + dir_k * length]
yield Polygon(np.concatenate((finite_part, extra_edge)))
第二步是将 Voronoi 多边形与边界多边形相交。我们还需要选择一个合适的直径传递给 voronoi_polygons
。
import matplotlib.pyplot as plt
from scipy.spatial import Voronoi
points = np.array([[0.1, -0.4], [0, 1.5], [0, 2.25], [1, 0], [1, 1], [1, 2],
[2, 0], [2.5, 1], [2, 2], [2.3, 2.3], [-0.5, -1.3], [-1.5, 3]])
boundary = np.array([[-5, -2], [3.4, -2], [4.7, 4], [2.7, 5.7], [-1, 4]])
x, y = boundary.T
plt.xlim(round(x.min() - 1), round(x.max() + 1))
plt.ylim(round(y.min() - 1), round(y.max() + 1))
plt.plot(*points.T, 'b.')
diameter = np.linalg.norm(boundary.ptp(axis=0))
boundary_polygon = Polygon(boundary)
for p in voronoi_polygons(Voronoi(points), diameter):
x, y = zip(*p.intersection(boundary_polygon).exterior.coords)
plt.plot(x, y, 'r-')
plt.show()
这绘制了上面 §2 中的最后一个数字。
关于python - Voronoi - 计算每个区域的确切边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23901943/
通过多次搜索和pytorch文档本身,我可以发现在嵌入层内部有一个查找表,用于存储嵌入向量。我无法理解的是: 在这一层的培训期间究竟发生了什么? 权重是多少,以及这些权重的梯度是如何计算的? 我的直觉
当应用程序有大量数据(400M)要写入非阻塞套接字时,write() 返回EWOULDBLOCK 或EAGAIN 当发送缓冲区变满时。 当套接字被(e)轮询时,我有时会看到发送缓冲区中有 7M 空间(
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我经常阅读一些编程语言对模块的支持(“一流”)(OCaml,Scala,TypeScript [?]),并且最近偶然发现了这样的答案,即在Scala的显着特征中引用模块作为一流公民。 我以为我很清楚模
我已经提交了一个自定义的开放图表故事,但它被拒绝并显示以下消息: 打开图表捐赠(行动类型)提交内容、操作、对象和使用说明必须以英文提交。您可以在应用程序面板的“本地化”选项卡中翻译操作和对象。 如果我
给定一个任意的 boolean 值列表,确定其中一个恰好为真的最优雅的方法是什么? 最明显的 hack 是类型转换:将 false 转换为 0,将 true 转换为 1,然后对它们求和,并返回 sum
这个问题在这里已经有了答案: When to use extern "C" in simple words? [duplicate] (7 个答案) 关闭 9 年前。 如果您想将此问题标记为重复问题
我是一名优秀的程序员,十分优秀!