【问题标题】:Python Random Map Generation with Perlin Noise使用 Perlin 噪声生成 Python 随机地图
【发布时间】:2013-07-22 03:26:51
【问题描述】:

最近,我一直在尝试克服我在一般编程中的主要弱点之一,即随机生成。我认为这将是一件容易的事,但缺乏简单的信息让我很生气。我不想听起来很愚蠢,但在我看来,来自this 这样的地方的大部分信息都是为​​上大学攻读理论数学的数学家写的。我只是不明白我要如何处理这些信息,以便将其应用于 Python 等语言的编程。

我已经工作了几天盯着方程式并尝试一次又一次地尝试,但在这些天之后,在一次又一次地撕开我的代码之后,所有一直正常工作的东西就是这个噪声发生器生成基本噪音:

import random
import math

random.seed(0)

def generateWhiteNoise(width,height):
    noise = [[r for r in range(width)] for i in range(height)]

    for i in range(0,height):
        for j in range(0,width):
            noise[i][j] = random.randint(0,1)

    return noise

noise = generateWhiteNoise(50,12)

for i in noise:
    print()
    for o in i:
        if(o == 0):
            print('-',end='')
        else:
            print('#',end='')

这段代码产生这个结果:

##-######--#--#-#--##-###-###---#-##-#-----#--##-#
#-#-##-##-#----##------##--#####-#-##---#--#-##---
-------#-#------#---#-#---###--#--#-###-----##-#--
######--#-#-#--####-###---#---###-##--#-#-##--####
-#----###--------##--##--##-#-#--#----###-####--##
---####-#--#--###-#-#--#--#####--####-#-##-##--#--
----#--####-#-#-#-#-#---#--###------###--#-######-
--###--#-###-------#-##--###---#-####----###-#####
#----##--##-#--##-###--#----#-#-##--##-#-##---###-
##---##----##--##--#--#--###-###-#--#-##---#------
-##----#-###---######---#-#---#---###---#---###-##
#--##-##-###-###---#--##-##--##-##-#-#-##--#-#-##-

我希望它最终会产生这样的结果:

--------------------------------------------------
------------------####----------------------------
-----------------#####----------------------------
----------------#####-----------------------------
---------------#####--------------###-------------
---------------#####--------------###-------------
---------------------------------####-------------
---######------------------------####-------------
---######------------###--------------------------
----########---------###--------------------------
-----#######---------###--------------------------
------###-----------------------------------------

如何才能消除我产生的白噪声,并将其变成孤岛?谁能用非常简单的方式给我解释一下?

我可能认为所有这些都是错误的。

【问题讨论】:

  • 我会采纳 user1483482 的建议。如果您想了解更多关于内部工作原理的信息,请尝试查看这里:devmag.org.za/2009/04/25/perlin-noise 我在 python 中复制了他的代码,它可以工作,但它非常很慢,即使使用 numpy。

标签: python random perlin-noise


【解决方案1】:

您可以使用Noise。好的编码员代码,很好的重用。但自 2018 年以来,开发就被放弃了。

这是very basic example(其他可以在 /examples 目录中找到)。

【讨论】:

  • 这是问题所在,我正在寻找实际产生的噪音,因为如果我要使用另一种没有说库的语言。
  • 请注意,Noise 库自 2018 年以来已被废弃 - 参见例如 github.com/caseman/noise/issues/31
【解决方案2】:

你的问题的直接答案是“不,你不能做你所要求的”,第二个答案是“是的,你认为这一切都错了”。

原因是您正在生成完全随机的噪声。您要的是相干噪声。它们是两种完全不同的动物,您无法从随机噪声中获得连贯的噪声。因此我的回答。

要解释原因,您必须理解我从excellent libnoise documentation 重复的这个简单陈述:


相干噪声

一种平滑的伪随机噪声。

相干噪声是由相干噪声函数产生的,它具有三个重要属性:

  • 传入相同的输入值将始终返回相同的输出值。
  • 输入值的微小变化会产生输出值的微小变化。
  • 输入值的较大变化会产生输出值的随机变化。

随机噪声不具有这些属性,因此完全不适合您想要实现的目标。

我建议学习Ken Perlin's latest (improved) reference implementation 和他的SIGGRAPH 2002 笔记。

如果您无法理解或实现这一点,则只需使用 libnoise 之类的库,这是一个出色且使用良好的 LGPL 库,最初用 C++ 编写,也已移植到许多其他语言。

【讨论】:

  • “你不能从随机噪声中得到连贯的噪声”——你可以通过多种方式做到这一点。最原始的方法是平均附近的值。 Perlin Noise 是从随机噪声中获取连贯噪声的著名方法。
  • "你不能从随机噪声中得到连贯的噪声"当然可以
  • 不,相干噪声来自伪随机噪声。随机噪声没有输入属性,当提供时总是提供相同的输出。随机噪声根本没有输入属性。检查您的来源。
【解决方案3】:

这是一个有趣的小问题,你可以用这种算法解决它:

  1. 生成小的均匀噪声
  2. 将其重新采样为更高的分辨率(为您提供平滑的噪声图像)
  3. 应用阈值获取 False/True 数组
  4. 将 False/True 映射到 '-'/'#'

加上一些打印格式,它工作得很好。示范:

import numpy as np
import sys
np.set_printoptions(threshold=sys.maxsize)
from scipy.ndimage.interpolation import zoom
arr = np.random.uniform(size=(4,4))
arr = zoom(arr, 8)
arr = arr > 0.5
arr = np.where(arr, '-', '#')
arr = np.array_str(arr, max_line_width=500)
print(arr)

输出:

[['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
 ['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']]

当然,像其他回答者所指出的 Perlin 或 Simplex 噪声会提供更好的外观。如果您想尝试这样做,请将第 1 步和第 2 步替换为 Perlin/Simplex 或任何其他可以抓取的噪音,然后重试。

【讨论】:

  • raise ValueError("threshold must be non-NAN 删除此行可解除程序崩溃,但仅显示部分数组
  • @reducingactivity 不确定我是否关注,你是什么意思?
  • np.set_printoptions(threshold=np.nan)raise ValueError("threshold must be non-NAN ... 崩溃
  • 签名好像改了,可以试试np.set_printoptions(threshold=sys.maxsize)吗?
【解决方案4】:

宁愿使用元胞自动机。您发现 here 的算法会创建您希望看到的类似模式:

. . . . . . . . . . . . . . .
. . . . . # # . . . . . # . .
. . . . # # # # . . . # # # .
. . . . . # # # # . . # # # .
. . . . . . # # # # # # # . .
. . . . . . # # # # # # # . .
. . . . # # # # # # # # # . .
. . . # # # # # # # # # # . .
. . # # # # # # . # . # # . .
. . # # # # # . . # . . . . .
. . . # # # # . . . # # # . .
. . . # # # # . . . # # # # .
. . # # # # . . . . . # # # .
. . # # # # . . . . . # # . .
. . . . . . . . . . . . . . .

【讨论】:

    【解决方案5】:

    这篇文章(以及同一项目中的其他文章)很好地介绍了编码问题。 C++ 代码。 https://code.google.com/p/fractalterraingeneration/wiki/Perlin_Noise

    这是一篇关于使用 Simplex 噪声算法的论文(在某些方面对原始 Perlin 噪声算法进行了改进)。它包括示例 Java 代码。 http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf

    最近也是同一作者将此代码设为公共域 http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java

    将这些概念翻译成 Python 应该不会太难,尽管 Python 的数据结构习语有点不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-12
      • 2020-08-30
      • 1970-01-01
      • 2013-06-30
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多