【问题标题】:Using PyGame to show Sci Py voronoi edges creates weird "star" effect使用 PyGame 显示 Sci Py voronoi 边缘会产生奇怪的“星形”效果
【发布时间】:2019-08-09 11:21:03
【问题描述】:

我正在尝试使用 SciPy 和 PyGame 在我随机生成的世界地图上创建和显示 Voronoi Diagram

我遇到的问题是,总是有一个点有奇怪的线条,忽略其他任何东西,并像星星或其他东西一样在地图上散布开来。从左上角和左下角可以看出,它们不会进入无穷大。

我怎样才能摆脱它?

显示内容:

我的代码:

import numpy
import random
import pygame
from scipy.spatial import Voronoi


def __generate_voronoi():
    """
    Randomly chooses various points within the x and y dimensions of the map.
    Then, uses SciPy to generate a voronoi diagram with them, and returns it.

    :return: SciPy voronoi diagram
    """

    point_arr = numpy.zeros([900, 2], numpy.uint16)

    for i in range(900):
        point_arr[i][0] = numpy.uint16(random.randint(0, 1600))
        point_arr[i][1] = numpy.uint16(random.randint(0, 900))

    return Voronoi(point_arr)


def draw_voronoi(pygame_surface):
    # generate voronoi diagram
    vor = __generate_voronoi()

    # draw all the edges
    for indx_pair in vor.ridge_vertices:
        start_pos = vor.vertices[indx_pair[0]]
        end_pos = vor.vertices[indx_pair[1]]

        pygame.draw.line(pygame_surface, (0, 0, 0), start_pos, end_pos)

【问题讨论】:

  • 这不是一个解决方案,但代码可以检查行长度 start_pos -> end_pos 并丢弃任何超过某个校准最大值的行。
  • @Kingsley 谢谢你,但我想看看我是否能找到即使该点靠近地图边界也能工作的东西。
  • ridge_vertices 中的索引可以包含 -1 值,表示图表边缘的一条线指向无穷远,而不是连接到 vertices 中的另一个点。您盲目地将这些值视为索引,从而导致在列表中碰巧位于最后的任何顶点出现一行。生成一个有意义的远端点来表示这些无限的线需要一些额外的计算 - 我建议查看 scipy.spatial.voronoi_plot_2d 的源代码作为起点。
  • @jasonharper 谢谢你,但我认为你在无穷大方面犯了一个错误。这些线条实际上并没有走向无穷大。查看图像的左上角和左下角。
  • @LuminousNutria 它们是应该走向无穷远的线,因此它们的索引为-1。在许多语言中,这是一种返回错误而不是在索引中的简单方法,但在 python 中,-1 是一个有效的索引。查看“/python_location/Lib/site-packages/scipy/spatial/_plotutils.py”第 173-188 行,了解内置实用程序的功能。

标签: python python-2.7 numpy scipy pygame


【解决方案1】:

感谢这里的耐心评论者,我了解到vor.vertices 将返回 -1 作为指向无穷大的点的第一个索引。这会产生一个问题,因为 python 将 -1 视为列表或数组的最后一个元素的索引。

我的问题的解决方案是不要从vor.vertices 绘制任何具有-1 索引的线。

我通过用以下代码替换 draw_voronoi() 函数来实现这一点:

def draw_voronoi(pygame_surface):

    # generate voronoi diagram
    vor = __generate_voronoi()

    # draw all the edges
    for indx_pair in vor.ridge_vertices:

        if -1 not in indx_pair:

            start_pos = vor.vertices[indx_pair[0]]
            end_pos = vor.vertices[indx_pair[1]]

            pygame.draw.line(pygame_surface, (0, 0, 0), start_pos, end_pos)

产生了这张图片:

【讨论】:

  • 这个问题(和答案)让我想起了 This 对另一个问题的回答,它也帮助我解决了另一个问题 question。我相信它们可能会帮助您了解 voronoi 图表,并且可能对您的游戏有所帮助。
  • @Aaron 我打算弄清楚如何让那些无限的线条看起来超出地图的边缘。再次感谢!
  • 那或者你可以重新实现我在第一条评论中提到的内置 scipy 实现。
  • @Aaron 我想我们可能有不同版本的_plotutils.py。在我的第 173-188 行只是voronoi_plot_2d() 函数的文档字符串的一部分。我不确定他们特别指出了什么。他们说,“指定点的大小返回 ------- fig : matplotlib.figure.Figure instance Figure for the plot See Also -------- Voronoi Notes ----- Requires Matplotlib。”
  • 好吧,我基本上只是想引用那个函数。我想这不是经常改变的东西。相关位是该函数如何识别finite_segmentsinfinite_segments,以及它如何计算一个有限点(相当远)来表示无限线。
猜你喜欢
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多