约束 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 顶点的域 的相关文章

  • 从另一个未排序的numpy数组中的数据查找未排序的numpy数组中值的索引位置[重复]

    这个问题在这里已经有答案了 我有一个 numpy 数组 A 其中包含可以按任何顺序排列的唯一 ID 例如A 1 3 2 我有第二个 numpy 数组 B 它记录了 ID 何时被使用 例如B 3 3 1 3 2 1 2 3 1 1 2 3 3
  • 使用 NumPy 函数计算 Pandas 的加权平均值

    假设我们有一个像这样的 pandas 数据框 a b id 36 25 2 40 25 3 46 23 2 40 22 5 42 20 5 56 39 3 我想执行一个操作 a div b 然后按 id 分组 最后使用 a 作为权重计算加权
  • 使用 scipy.stats 计算条件期望

    假设 x Poisson 2 5 我想计算类似 E x x gt 2 的东西 我认为这可以通过 dist expect 运算符来完成 即 D stats poisson 2 5 cond expect D dist expect lambd
  • 用布尔数组屏蔽一系列

    这给我带来了很多麻烦 我对 numpy 数组与 pandas 系列的不兼容感到困惑 例如 当我使用系列创建布尔数组时 x np array 1 2 3 4 5 6 7 y pd Series 1 2 3 4 5 6 7 delta np p
  • 合并多边形的高效算法

    我有一个多边形列表 在这个列表中 一些多边形重叠 或者接触其他多边形 我的任务是合并所有相互重叠或接触的多边形 我有一个union执行此操作的方法 做到这一点最有效的方法是什么 我目前能想到的是循环遍历多边形列表 检查合并列表以查看该多边形
  • 有一些 numpy.map 吗?

    我可能在这里遗漏了一些明显的东西 但我遗漏了一个功能numpy map 这与 Python 的相同map函数 但将输出收集在numpy大批 例如 我可以有一个图像生成器genImage i 生成 2D 图像 大小 m n 基于单个输入 我想
  • 使用 cv2 在 python 中创建多通道零垫

    我想用 cv2 opencv 包装器在 python 中创建一个多通道 mat 对象 我在网上找到了一些例子 其中 c Mat zeros 被 numpy zeros 替换 这看起来不错 但似乎没有多通道类型适合 看代码 import cv
  • OpenCV 旋转图像而不裁剪澄清

    我想扩展这个主题 参考用户 Lars Schillingmann 给出的这个 SO 问题和接受的答案 在 C 中的 OpenCV 中旋转图像而不裁剪 https stackoverflow com questions 22041699 ro
  • 内存高效的随机数迭代器,无需替换

    我觉得这应该很容易 但经过多次搜索和尝试后我找不到答案 基本上 我有大量的物品 我想以随机顺序进行采样 而不需要更换 在本例中 它们是二维数组中的单元 我用于较小数组的解决方案不会转换 因为它需要对内存数组进行改组 如果我必须采样的数量很小
  • 如何在 ndarray 内创建一个球体? [复制]

    这个问题在这里已经有答案了 我有一个 ndarray 大小32x32x32 我想在数组内创建一个球体 其中心位于 x y 半径为 4 像素 球体的值为 1 而数组的值为 0 这如何在 python 中完成 这是生成数组的代码 import
  • python:numpy 中的组合掩码

    在 numpy 数组中我想替换所有nan and inf变成一个固定的数字 我可以一步完成这一操作以节省计算时间 数组真的很大 吗 a np arange 10 0 a 3 np nan a 5 np inf a 7 np inf a 0
  • 使用 to_categorical 转换 np.array 时出现内存问题

    我有一个像这样的 numpy 数组 0 1 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 我这样改造它以减少内存需求 x val x val asty
  • python中稀疏矩阵的相关系数?

    有谁知道如何从Python中的一个非常大的稀疏矩阵计算相关矩阵 基本上 我正在寻找类似的东西numpy corrcoef这将适用于 scipy 稀疏矩阵 您可以从协方差矩阵相当直接地计算相关系数 如下所示 import numpy as n
  • NumPy 中按列增长矩阵

    在纯Python中 你可以很容易地逐列增长矩阵 data for i in something newColumn getColumnDataAsList i data append newColumn NumPy http en wiki
  • Python:numpy/pandas 根据条件更改值

    我想知道是否有更快 更 Pythonic 的方法来执行以下操作 例如使用一些内置方法 给定一个 pandas DataFrame 或 numpy 浮点数组 如果该值等于或小于 0 5 我需要计算倒数并乘以 1 并用新计算的值替换旧值 转变
  • “扩展”numpy ndarray 的好方法?

    有没有 扩展 numpy ndarray 的好方法 假设我有一个像这样的 ndarray 1 2 3 4 我希望每行通过填充零来包含更多元素 1 2 0 0 0 3 4 0 0 0 我知道一定有一些蛮力的方法可以做到这一点 比如构造一个带有
  • 为什么具有复杂无穷大的 NumPy 运算会导致有趣的结果?

    我注意到复杂的无穷大的有趣结果 In 1 import numpy as np In 2 np isinf 1j np inf Out 2 True In 3 np isinf 1 1j np inf Out 3 True In 4 np
  • 如何将 numpy.matrix 提高到非整数幂?

    The 运算符为numpy matrix不支持非整数幂 gt gt gt m matrix 1 0 0 5 0 5 gt gt gt m 2 5 TypeError exponent must be an integer 我想要的是 oct
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • 从 pygame 获取 numpy 数组

    我想通过 python 访问我的网络摄像头 不幸的是 由于网络摄像头的原因 openCV 无法工作 Pygame camera 使用以下代码就像魅力一样 from pygame import camera display camera in

随机推荐

  • 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 字段中有点 这些点有一点重叠 所以我稍微 抖动 它们 以使它们不重叠