2013-07-22 17 views
5

Recentemente, ho tentato di sconfiggere uno dei miei principali punti deboli nella programmazione in generale, generazione casuale. Ho pensato che sarebbe stata una cosa facile da fare, ma la mancanza di informazioni semplici mi sta uccidendo. Non voglio sembrare stupido, ma mi sembra che la maggior parte delle informazioni provenienti da posti come this siano scritte per matematici che sono andati al college per laurearsi in matematica teorica. Semplicemente non capisco cosa intendo fare con quella informazione per applicarla alla programmazione in un linguaggio come python.Generazione casuale di mappe Python con rumore Perlin

Ho lavorato alcuni giorni fissando equazioni e tentando tentativo dopo tentativo, ma dopo tutti quei giorni, dopo aver strappato il mio codice ancora e ancora, tutto ciò che ha funzionato correttamente per tutto questo tempo è questo generatore di rumore per generare un rumore di fondo:

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='') 

questo codice produce questo risultato:

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

sono voler che alla fine di produrre qualcosa di simile a questo:

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

Come posso eliminare il rumore bianco generato e trasformarlo in isole? Qualcuno può spiegarlo in un modo molto semplicistico per me?

Potrei pensare a tutto questo molto male.

+1

Vorrei prendere il suggerimento di user1483482. Se vuoi saperne di più sul funzionamento interno prova a guardare qui: http://devmag.org.za/2009/04/25/perlin-noise/ Ho riprodotto il suo codice in python, e funziona, ma è ** Molto ** lento, anche con Numpy. – seth

risposta

5

Basta usare Noise. Codice di buon codificatore, grande riutilizzo.

Ecco uno very basic example (gli altri possono essere trovati nella directory/examples).

+0

Ecco il problema, sto cercando di generare effettivamente il rumore, perché se dovessi usare un altro linguaggio che non ha detto la libreria. –

0

Questo articolo (e altri nello stesso progetto) è una buona introduzione ai problemi di codifica. Codice C++ https://code.google.com/p/fractalterraingeneration/wiki/Perlin_Noise

Ecco un documento sull'utilizzo dell'algoritmo di disturbo Simplex (migliora in certi modi l'algoritmo Perlin Noise originale). Include codice Java di esempio. http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf

anche lo stesso autore ha reso questo codice di dominio pubblico di recente http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java

Non dovrebbe essere troppo difficile da tradurre i concetti in Python, anche se idiomi di Python per strutture di dati sono un po 'diverso.

1

Piuttosto utilizzare gli automi cellulari. L'algoritmo che trovate here crea modelli simili che si desidera vedere:

. . . . . . . . . . . . . . . 
. . . . . # # . . . . . # . . 
. . . . # # # # . . . # # # . 
. . . . . # # # # . . # # # . 
. . . . . . # # # # # # # . . 
. . . . . . # # # # # # # . . 
. . . . # # # # # # # # # . . 
. . . # # # # # # # # # # . . 
. . # # # # # # . # . # # . . 
. . # # # # # . . # . . . . . 
. . . # # # # . . . # # # . . 
. . . # # # # . . . # # # # . 
. . # # # # . . . . . # # # . 
. . # # # # . . . . . # # . . 
. . . . . . . . . . . . . . . 
3

La risposta diretta alla tua domanda è "No, non si può fare quello che chiedete", e la seconda risposta è "Sì , stai pensando a tutto ciò che è sbagliato ".

La ragione è che si sta generando un rumore completamente casuale. Quello che chiedi è un rumore coerente. Sono due animali completamente diversi e non è possibile ottenere un rumore coerente dal rumore casuale. Quindi la mia risposta.

di spiegare perché, è necessario comprendere questa semplice dichiarazione che ripeto dal excellent libnoise documentation:


Coherent rumore

Un tipo di rumore pseudocasuale liscia.

rumore coerente è generato da una funzione coerente rumore, che ha tre importanti proprietà:

  • passano nella stesso valore d'ingresso restituirà sempre lo stesso valore di uscita.
  • Un piccolo cambiamento nel valore di ingresso produrrà una piccola modifica nel valore di uscita.
  • Un grande cambiamento nel valore di ingresso produrrà una variazione casuale nel valore di uscita.

rumore a caso non ha queste proprietà, e quindi è del tutto inadatto per ciò che si sta cercando di ottenere.

Suggerirei di studiare Ken Perlin's latest (improved) reference implementation e le sue note SIGGRAPH 2002.

Se non riesci a comprenderlo o implementarlo, utilizza solo una libreria come libnoise, una libreria LGPL eccellente e ben utilizzata originariamente in C++, che è stata anche trasferita in molte altre lingue.

0

Si tratta di un piccolo problema di divertimento, si può risolvere con questo tipo di algoritmo:

  1. generare un piccolo rumore uniforme
  2. ridefinirla per una risoluzione più alta (dando un'immagine rumore liscia)
  3. Applicare la soglia per ottenere un/vero Falso gamma
  4. Mappa Falso/vero a '-'/'#'

E con un po 'di prin la formattazione funziona bene. Dimostrazione:

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) 

uscita:

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

Naturalmente un Perlin o Simplex rumore come altri answerers indicate darebbe un aspetto leggermente migliore. Se vuoi provarlo, sostituisci i passaggi 1 e 2 con Perlin/Simplex o qualsiasi altro rumore che puoi catturare e riprovare.