使用柏林噪声生成 Python 随机地图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17779480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Random Map Generation with Perlin Noise
提问by NAME__
Recently, I've been attempting to defeat one of my main weaknesses in programming in general, random generation. I thought it would be an easy thing to do, but the lack of simple information is killing me on it. I don't want to sound dumb, but it feels to me like most of the information from places like thisare written for mathematicians who went to college to graduate in theoretical mathematics. I just don't understand what I'm meant to do with that information in order to apply it to programming in a language such as python.
最近,我一直试图克服我在编程中的一个主要弱点,即随机生成。我认为这将是一件容易的事情,但缺乏简单的信息让我很沮丧。我不想音哑,但感觉对我来说,大部分信息来自类似的地方这是为谁上了大学毕业在理论数学的数学家写的。我只是不明白我打算用这些信息做什么,以便将它应用到 Python 等语言的编程中。
I've been working a few days staring at equations and attempting attempt after attempt, but still after all those days, after ripping my code apart again and again, all that's been working properly this entire time is this noise generator to generate basic noise:
我已经工作了几天盯着方程并尝试一次又一次的尝试,但仍然在那些日子之后,在一次又一次地撕开我的代码之后,一直在正常工作的是这个噪声发生器来产生基本的噪声:
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='')
This code produces this result:
此代码产生此结果:
##-######--#--#-#--##-###-###---#-##-#-----#--##-#
#-#-##-##-#----##------##--#####-#-##---#--#-##---
-------#-#------#---#-#---###--#--#-###-----##-#--
######--#-#-#--####-###---#---###-##--#-#-##--####
-#----###--------##--##--##-#-#--#----###-####--##
---####-#--#--###-#-#--#--#####--####-#-##-##--#--
----#--####-#-#-#-#-#---#--###------###--#-######-
--###--#-###-------#-##--###---#-####----###-#####
#----##--##-#--##-###--#----#-#-##--##-#-##---###-
##---##----##--##--#--#--###-###-#--#-##---#------
-##----#-###---######---#-#---#---###---#---###-##
#--##-##-###-###---#--##-##--##-##-#-#-##--#-#-##-
I'm wanting it to eventually produce something like this:
我希望它最终产生这样的东西:
--------------------------------------------------
------------------####----------------------------
-----------------#####----------------------------
----------------#####-----------------------------
---------------#####--------------###-------------
---------------#####--------------###-------------
---------------------------------####-------------
---######------------------------####-------------
---######------------###--------------------------
----########---------###--------------------------
-----#######---------###--------------------------
------###-----------------------------------------
How can I manage to smooth out the white-noise I generate, and turn it into islands? Can anyone explain it in a very simplistic way for me?
我怎样才能设法消除我产生的白噪声,并将其变成孤岛?谁能以非常简单的方式为我解释一下?
I may be thinking about all of this very wrong.
我可能正在考虑所有这些非常错误的事情。
回答by user1483482
Just use Noise. Good coders code, great reuse.
只需使用噪音。好的编码器代码,很好的重用。
Here's a very basic example(others can be found in the /examples directory).
回答by KarlM
This article (and others in the same project) is a pretty good introduction to the coding issues. C++ code. https://code.google.com/p/fractalterraingeneration/wiki/Perlin_Noise
这篇文章(以及同一项目中的其他文章)很好地介绍了编码问题。C++ 代码。 https://code.google.com/p/fractalterraingeneration/wiki/Perlin_Noise
Here is a paper on using the Simplex noise algorithm (improves in certain ways on the original Perlin Noise algorithm). It includes example Java code. http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
这是一篇关于使用 Simplex 噪声算法的论文(在原始 Perlin 噪声算法的某些方面进行了改进)。它包括示例 Java 代码。http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
Also the same author made this code public domain recently http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java
也是同一位作者最近将这段代码公之于众 http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java
It shouldn't be too difficult to translate the concepts into Python, although Python's idioms for data structures are a bit different.
将这些概念翻译成 Python 应该不会太难,尽管 Python 的数据结构习语有点不同。
回答by dirkk0
Rather use cellular automatons. The algorithm that you find herecreates similar patterns that you you would like to see:
而是使用元胞自动机。您在此处找到的算法会创建您希望看到的类似模式:
. . . . . . . . . . . . . . .
. . . . . # # . . . . . # . .
. . . . # # # # . . . # # # .
. . . . . # # # # . . # # # .
. . . . . . # # # # # # # . .
. . . . . . # # # # # # # . .
. . . . # # # # # # # # # . .
. . . # # # # # # # # # # . .
. . # # # # # # . # . # # . .
. . # # # # # . . # . . . . .
. . . # # # # . . . # # # . .
. . . # # # # . . . # # # # .
. . # # # # . . . . . # # # .
. . # # # # . . . . . # # . .
. . . . . . . . . . . . . . .
回答by Ian Macintosh
The direct answer to your question is "No, you cannot do what you are asking", and the second answer is "Yes, you are thinking about this all wrong".
你的问题的直接答案是“不,你不能做你所要求的”,第二个答案是“是的,你把这一切都想错了”。
The reason is that you are generating completely random noise. What you are asking for is coherent noise. They are two completely different animals and you cannot get coherent noise from random noise. Hence my answer.
原因是您正在产生完全随机的噪音。您要的是相干噪声。它们是两种完全不同的动物,您无法从随机噪声中获得相干噪声。因此我的回答。
To explain why, you must understand this simple statement which I am repeating from the excellent libnoise documentation:
要解释原因,您必须理解我从优秀的 libnoise 文档中重复的这个简单陈述:
Coherent noise
相干噪声
A type of smooth pseudorandom noise.
一种平滑的伪随机噪声。
Coherent noise is generated by a coherent-noise function, which has three important properties:
相干噪声由相干噪声函数产生,它具有三个重要特性:
- Passing in the same input value will always return the same output value.
- A small change in the input value will produce a small change in the output value.
- A large change in the input value will produce a random change in the output value.
- 传入相同的输入值将始终返回相同的输出值。
- 输入值的微小变化会产生输出值的微小变化。
- 输入值的较大变化将产生输出值的随机变化。
Random noise does not have these properties, and therefore is completely unsuitable for what you are trying to achieve.
随机噪声没有这些属性,因此完全不适合您要实现的目标。
I would suggest studying Ken Perlin's latest (improved) reference implementationand his SIGGRAPH 2002notes.
我建议研究Ken Perlin 的最新(改进的)参考实现和他的SIGGRAPH 2002笔记。
If you cannot understand or implement this, then just use a library such as libnoise, an excellent and well used LGPL library originally in C++ which has also been ported to many other languages.
如果您无法理解或实现这一点,那么只需使用诸如libnoise 之类的库,这是一个出色且使用良好的 LGPL 库,最初使用 C++编写,也已移植到许多其他语言中。
回答by Overdrivr
This is a fun little problem, you can solve it with this sort of algorithm:
这是一个有趣的小问题,你可以用这种算法解决它:
- generate a small uniform noise
- resample it to a higher resolution (giving you a smooth noise image)
- Apply threshold to get a False/True array
- Map False/True to '-'/'#'
- 产生小的均匀噪声
- 将其重新采样到更高的分辨率(为您提供平滑的噪声图像)
- 应用阈值以获取 False/True 数组
- 将 False/True 映射到 '-'/'#'
And with a bit of printing formatting it works well. Demonstration:
通过一些打印格式,它运行良好。示范:
import numpy as np
np.set_printoptions(threshold=np.nan)
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)
output:
输出:
[['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '#' '#' '#']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['#' '#' '#' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']
['-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-']]
Of course a Perlin or Simplex noise like other answerers indicated would give a slightly better look. If you want to try that, replace steps 1 and 2 with Perlin/Simplex or any other noise you can grab and try again.
当然,像其他回答者指出的那样,Perlin 或 Simplex 噪声会更好看。如果您想尝试,请将步骤 1 和 2 替换为 Perlin/Simplex 或您可以抓取的任何其他噪音,然后重试。