约束 Qhull 生成的 Voronoi 顶点的域

2024-02-02

简而言之,我的问题是:是否可以约束 Qhull 生成的 Voronoi 顶点的域?如果是的话,怎样才能做到这一点呢?

我的上下文问题:我正在研究数据可视化,其中我在 2D 字段中有点。这些点有一点重叠,所以我稍微“抖动”它们,以使它们不重叠。

我目前执行此任务的方法是使用劳埃德算法 https://en.wikipedia.org/wiki/Lloyd%27s_algorithm移动点。劳埃德算法本质上采用初始点位置,计算 Voronoi 图,并在算法的每次迭代期间将每个点移动到其 Voronoi 区域的中心。

下面是一个 Python 示例:

from scipy.spatial import Voronoi
from scipy.spatial import voronoi_plot_2d
import matplotlib.pyplot as plt
import numpy as np
import sys

class Field():
  '''
  Create a Voronoi map that can be used to run Lloyd relaxation on an array of 2D points.
  For background, see: https://en.wikipedia.org/wiki/Lloyd%27s_algorithm
  '''

  def __init__(self, arr):
    '''
    Store the points and bounding box of the points to which Lloyd relaxation will be applied
    @param [arr] arr: a numpy array with shape n, 2, where n is number of points
    '''
    if not len(arr):
      raise Exception('please provide a numpy array with shape n,2')

    x = arr[:, 0]
    y = arr[:, 0]
    self.bounding_box = [min(x), max(x), min(y), max(y)]
    self.points = arr
    self.build_voronoi()

  def build_voronoi(self):
    '''
    Build a Voronoi map from self.points. For background on self.voronoi attrs, see:
    https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.spatial.Voronoi.html
    '''
    eps = sys.float_info.epsilon
    self.voronoi = Voronoi(self.points)
    self.filtered_regions = [] # list of regions with vertices inside Voronoi map
    for region in self.voronoi.regions:
      inside_map = True    # is this region inside the Voronoi map?
      for index in region: # index = the idx of a vertex in the current region

          # check if index is inside Voronoi map (indices == -1 are outside map)
          if index == -1:
            inside_map = False
            break

          # check if the current coordinate is in the Voronoi map's bounding box
          else:
            coords = self.voronoi.vertices[index]
            if not (self.bounding_box[0] - eps <= coords[0] and
                    self.bounding_box[1] + eps >= coords[0] and
                    self.bounding_box[2] - eps <= coords[1] and
                    self.bounding_box[3] + eps >= coords[1]):
              inside_map = False
              break

      # store hte region if it has vertices and is inside Voronoi map
      if region != [] and inside_map:
        self.filtered_regions.append(region)

  def find_centroid(self, vertices):
    '''
    Find the centroid of a Voroni region described by `vertices`, and return a
    np array with the x and y coords of that centroid.

    The equation for the method used here to find the centroid of a 2D polygon
    is given here: https://en.wikipedia.org/wiki/Centroid#Of_a_polygon

    @params: np.array `vertices` a numpy array with shape n,2
    @returns np.array a numpy array that defines the x, y coords
      of the centroid described by `vertices`
    '''
    area = 0
    centroid_x = 0
    centroid_y = 0
    for i in range(len(vertices)-1):
      step = (vertices[i, 0] * vertices[i+1, 1]) - (vertices[i+1, 0] * vertices[i, 1])
      area += step
      centroid_x += (vertices[i, 0] + vertices[i+1, 0]) * step
      centroid_y += (vertices[i, 1] + vertices[i+1, 1]) * step
    area /= 2
    centroid_x = (1.0/(6.0*area)) * centroid_x
    centroid_y = (1.0/(6.0*area)) * centroid_y
    return np.array([centroid_x, centroid_y])

  def relax(self):
    '''
    Moves each point to the centroid of its cell in the Voronoi map to "relax"
    the points (i.e. jitter them so as to spread them out within the space).
    '''
    centroids = []
    for region in self.filtered_regions:
      vertices = self.voronoi.vertices[region + [region[0]], :]
      centroid = self.find_centroid(vertices) # get the centroid of these verts
      centroids.append(list(centroid))

    self.points = centroids # store the centroids as the new point positions
    self.build_voronoi() # rebuild the voronoi map given new point positions

##
# Visualize
##

# built a Voronoi diagram that we can use to run lloyd relaxation
field = Field(points)

# plot the points with no relaxation relaxation
plt = voronoi_plot_2d(field.voronoi, show_vertices=False, line_colors='orange', line_alpha=0.6, point_size=2)
plt.show()

# relax the points several times, and show the result of each relaxation
for i in range(6): 
  field.relax() # the .relax() method performs lloyd relaxation
  plt = voronoi_plot_2d(field.voronoi, show_vertices=False, line_colors='orange', line_alpha=0.6, point_size=2)
  plt.show()

正如我们所看到的,在每次迭代期间(第 2 帧和第 3 帧),原始数据集中的点(第 1 帧,顶部)重叠越来越少,这很棒!

这种方法的问题是我目前正在从图中删除那些 voronoi 区域边界超出初始数据集域的点。 (如果我不这样做,最外面的点很快就会射入超空间并远离其他点。)这最终意味着我最终会丢弃点,这不好。

我认为我可以通过约束 Qhull Voronoi 域来解决这个问题,以便仅在原始数据域内创建 Voronoi 顶点。

可以这样约束Qhull吗?其他人可以提供的任何帮助将不胜感激!


Update

在收到@tfinniga 的出色回复后,我整理了一个博客文章 https://douglasduhaime.com/posts/lloyd-iteration.html详细介绍了有界和无界形式的劳埃德迭代。我还整理了一个小包lloyd https://github.com/duhaime/lloyd以便更轻松地在数据集上运行有界 Lloyd 迭代。我想分享这些资源,以防它们帮助其他人进行相关分析。


您遇到的核心问题是劳埃德算法没有任何限制,因此点会爆炸。有两种方法可以解决此问题:

  1. 获取您获得的 voronoi 图,并在计算质心之前手动将其剪切到边界矩形。这将为您提供正确的解决方案 - 您可以根据维基百科文章中链接的示例对其进行测试,并确保其匹配。

  2. 添加点的人工边界。例如,您可以在边界框的 4 个角处添加点,或者在每侧添加一些点,但不要移动这些点。这些将阻止内部点爆炸。这不会为您提供劳埃德算法的“正确”结果,但可能会为您提供对可视化有用的输出,并且更容易实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

约束 Qhull 生成的 Voronoi 顶点的域 的相关文章

  • 约束 3D 表面的 RBF 插值以保持曲率

    我的任务是开发一种算法 给定一组表示现有表面测量值的稀疏点 我们就可以计算表面上任何点的 z 坐标 面临的挑战是找到一种合适的插值方法 该方法可以在仅给定几个点的情况下重新创建 3D 表面 并推断出超出包含初始测量值的范围的值 对于许多插值
  • 在python中将二维数组转换为彩色图像

    我有这样的二维整数列表 list1 1 30 50 21 45 9 97 321 100 接下来我将把它转换为 numpy 数组 myarr np asarray list1 接下来我将使用 PIL 将其转换为图像 如下所示 img Ima
  • 求解超定系统最小二乘的最快方法

    我有一个大小为 m n 的矩阵 A m 阶约为 100K n 阶约为 500 和向量 b 另外 我的矩阵是病态的并且等级不足 现在我想找出 Ax b 的最小二乘解 为此我比较了一些方法 scipy linalg lstsq 时间 剩余 14
  • 读取并绘制从大文件中读取的数据

    我们有相当大的文件 大约为 1 1 5 GB 主要是日志文件 其中包含易于解析为 csv 的原始数据 随后应该将其绘制成图表以生成一组图形图像 目前 我们正在使用 bash 脚本将原始数据转换为 csv 文件 其中仅包含需要绘制图表的数字
  • 如何调试 numpy 掩码

    这个问题与this one https stackoverflow com q 73672739 11004423 我有一个正在尝试矢量化的函数 这是原来的函数 def aspect good angle float planet1 goo
  • 使用 numpy.argsort 的输出就地排序

    我有两个数组 A 和 B 我想根据 A 对 A 和 B 进行排序 所以我这样做 sort order numpy argsort A A A sort order B B sort order 问题是 A 和 B 都非常非常大 因此上述情况
  • 从三点求圆心的算法是什么?

    我在圆的圆周上有三个点 pt A A x A y pt B B x B y pt C C x C y 如何计算圆心 在Processing Java 中实现它 我找到了答案并实施了一个可行的解决方案 pt circleCenter pt A
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • 使用 OpenCV 和/或 Numpy 对两个图像进行 Alpha 混合 [重复]

    这个问题在这里已经有答案了 我想将一个填充纯色的半透明矩形添加到已加载的半透明 PNG 中 这是我正在使用的输入图像示例 该图像加载了标准cv2 IMREAD UNCHANGED标志 以便完美保留 alpha 通道 该输入图像存储在imag
  • 组和平均 NumPy 矩阵

    假设我有一个任意的 numpy 矩阵 如下所示 arr 6 0 12 0 1 0 7 0 9 0 1 0 8 0 7 0 1 0 4 0 3 0 2 0 6 0 1 0 2 0 2 0 5 0 2 0 9 0 4 0 3 0 2 0 1 0
  • 将一维数组转换为下三角矩阵

    我想将一维数组转换为较低的零对角矩阵 同时保留所有数字 我知道numpy tril函数 但它用零替换了一些元素 我需要扩展矩阵以包含所有原始数字 例如 10 20 40 46 33 14 12 46 52 30 59 18 11 22 30
  • numpy:大量线段/点的快速规则间隔平均值

    我沿着一维线有许多 约 100 万个 不规则间隔的点 P 这些标记线段 这样 如果点是 0 x a x b x c x d 则线段从 0 gt x a x a gt x b x b gt x c x c gt x d 等 我还有每个段的 y
  • 在 scipy 中创建新的发行版

    我试图根据我拥有的一些数据创建一个分布 然后从该分布中随机抽取 这是我所拥有的 from scipy import stats import numpy def getDistribution data kernel stats gauss
  • 有没有办法在 JTS 中将自相交多边形转换为多重多边形?

    取无效多边形POLYGON 0 100 100 100 0 0 100 0 0 100 一个带有未声明交点的煮蛋定时器形状 许多说明说 JTS 可以使用以下命令创建此版本的有效版本 buffer method Geometry input
  • 2d 图像点和 3d 网格之间的交点

    Given 网格 源相机 我有内在和外在参数 图像坐标 2d Output 3D 点 是从相机中心发出的光线穿过图像平面上的 2d 点与网格的交点 我试图找到网格上的 3d 点 This is the process From Multip
  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • 高效创建抗锯齿圆形蒙版

    我正在尝试创建抗锯齿 加权而不是布尔 圆形掩模 以制作用于卷积的圆形内核 radius 3 no of pixels to be 1 on either side of the center pixel shall be decimal a
  • Numpy uint8_t 数组到 vtkImageData

    我正在尝试拍摄一个或三个通道的 2D 图像并使用 VTK 中显示它们vtkImageActor 据我了解 要显示的当前帧可以通过调用来更新SetImageData on vtkImageActor并提供一个实例vtkImageData 我已
  • 将二维数组放入 Pandas 系列中

    我有一个 2D Numpy 数组 我想将其放入 pandas 系列 而不是 DataFrame 中 gt gt gt import pandas as pd gt gt gt import numpy as np gt gt gt a np
  • 将 numpy 代码点数组与字符串相互转换

    我有一个很长的 unicode 字符串 alphabet range 0x0FFF mystr join chr random choice alphabet for in range 100 mystr re sub W mystr 我想

随机推荐

  • Node.js mongodb 中的 db.getUser

    与 MongoDB shell 命令等效的命令是什么db getUser and db getUsers在 Node js MongoDB 2 x 中 我在驱动程序文档中看到db addUser and db removeUser存在但没有
  • WordPress webp 图像预览

    我已经使用以下代码更新了 wordpress 以允许 webp 上传 function webp upload mimes existing mimes existing mimes webp image webp return exist
  • 测试期间随机抛出“InvalidCastException”

    在 WatiN UI 测试中 我遇到一个问题 在运行测试时 错误有时会抛出以下错误 InvalidCastException 未由用户代码处理 无法将类型为 mshtml HTMLDocumentClass 的 COM 对象转换为接口类型
  • 在Java Servlet中读取Ajax发送的JQuery数据

    这是我的 Ajax 代码 var myJSONObject bindings ircEvent PRIVMSG method newURI regex http ajax url ships data myJSONObject succes
  • 如何在 Visual Studio 2012 中加载符号

    当我调试我的应用程序时 我看到消息 找不到或打开 PDB 文件 我似乎记得能够在调试应用程序时指定 PDB 文件的位置 我怎样才能做到这一点 我正在使用 Visual Studio 2012 添加符号位置 打开设置 工具 gt 选项 gt
  • 如何修复拥挤的 tmap 图例中的垂直空间 [R]

    如何修复 tmap 图例中的垂直空间问题 如链接的基本 R 示例中所示的问题 图例中的垂直空间 https stackoverflow com questions 38332355 vertical spaces in legend y i
  • 从下拉框中获取文本

    这将获取我的下拉菜单中选择的任何值 document getElementById newSkill value 然而 我无法找出下拉菜单当前显示的文本要查找的属性 我尝试了 文本 然后查看了W3学校 http w3schools com
  • 如何在 Python 中处理 YAML 流

    我有一个命令行应用程序 它以以下形式连续输出 YAML 数据 col0 datum0 col1 datum1 col2 datum2 col0 datum0 col1 datum1 col2 datum2 它永远这样做 我想编写一个Pyth
  • 在 Symfony 中激活 StringLoader Twig 扩展

    我正在尝试激活Twig StringLoader 扩展 http twig sensiolabs org doc functions template from string html在 Symfony 2 3 项目中 但无法获得正确的 y
  • 如何在reactjs中上传到Firebase存储之前调整图像大小

    我正在尝试调整用户上传的图像大小 以提高我的网站效率并限制我的存储使用量 我从包中创建了一个名为 resizeFile 的函数 react image file resizer 现在我正在努力解决的是在上传到 firebase 存储之前如何
  • 模式匹配在 bash 脚本中不起作用

    使用模式匹配 file1 不能在 bash 脚本中工作 但可以在命令行中工作 例如 ls file1 file2 这将列出目录中的所有文件 除了file1 and file2 当在脚本中执行该行时 会显示此错误 script sh line
  • 如何查询一个域的用户是否是另一个 AD 域中的组的成员?

    我有一系列应用程序 它们都使用我创建的相同的 C Net 2 0 代码来检查用户是否是 Active Directory 组的成员 直到最近 当我将来自另一个受信任的 AD 域的用户添加到我的 AD 组之一时 我的代码才出现任何问题 我的问
  • 更改选择框选项背景颜色

    我有一个选择框 当单击选择框并显示所有选项时 我试图更改选项的背景颜色 body background url http subtlepatterns com patterns black linen v2 png repeat selec
  • 从 mongodb id 获取时间戳

    如何从 MongoDB id 获取时间戳 时间戳包含在 mongoDB id 的前 4 个字节中 请参阅 http www mongodb org display DOCS Object IDs http www mongodb org d
  • Objective-C 中 .Net Unicode 编码的等价物是什么?

    Objective C 中 Net 的等价物是什么System Text Encoding Unicode 我努力了 NSUnicode字符串编码 NSUTF8字符串编码 NSUTF16字符串编码 以上都没有正确地将文本转换回来 根据htt
  • 提取序列(列表) Prolog

    给定一个列表 例如 1 2 3 7 2 5 8 9 3 4 我如何提取列表中的序列 序列被定义为有序列表 通常我会说 n 元组 但在序言中我被告知元组被称为序列 因此 我们希望在下一个元素小于前一个元素的位置处剪切列表 所以对于清单 1 2
  • 如何修复“不明确”的函数调用?

    我正在开发一个 C 类程序 我的编译器抱怨 不明确 的函数调用 我怀疑这是因为有几个函数定义了不同的参数 我如何告诉编译器我想要哪一个 除了特定情况的修复之外 是否有通用规则 例如类型转换 可以解决此类问题 Edit 就我而言 我尝试打电话
  • 如果存在警报,WebDriver 屏幕截图将不起作用。使用c#.net如何处理?

    我正在使用 ASP net C net 内联网应用程序 Selenium Webdriver 用于测试应用程序 一页输入相同的名称 显示警报消息 已存在 使用 ajax 的服务器端警报 我想用 screenshort 捕获该警报消息 Sel
  • 为什么在删除元素/属性之前要检查它?

    In the 使用属性节点中的章节学习 Javascript 现代 Javascript 基础知识实践指南 http learningjsbook com 作者 Tim Wright 在第 73 页说道 删除属性就像获取属性一样简单 我们只
  • 约束 Qhull 生成的 Voronoi 顶点的域

    简而言之 我的问题是 是否可以约束 Qhull 生成的 Voronoi 顶点的域 如果是的话 怎样才能做到这一点呢 我的上下文问题 我正在研究数据可视化 其中我在 2D 字段中有点 这些点有一点重叠 所以我稍微 抖动 它们 以使它们不重叠