Sto studiando alcune delle varie implementazioni per il rumore coerente (so che ci sono librerie, ma questo è principalmente per la mia edificazione e curiosità) e come puoi usarlo, e c'è un problema Ho con la cosa del rumore Perlin originale.Intervallo di uscita del rumore Perlin
Secondo this frequently linked Math FAQ, l'intervallo di uscita sarà compreso tra -1
e 1
, ma non capisco come il valore possa trovarsi in tale intervallo.
Come ho capito, l'algoritmo è fondamentalmente questo: ogni punto della griglia ha un vettore di gradiente casuale associato di lunghezza 1
. Quindi, per ciascun punto, per tutti e quattro i punti della griglia circostante, si calcola il prodotto punto del gradiente casuale e il vettore che passa da quel punto della griglia. Quindi utilizzi una curva di facilità di fantasia e un'interpolazione lineare per portarlo a un valore.
Ma, ecco il mio problema: questi prodotti puntini sono, di tanto in tanto, al di fuori dell'intervallo [-1, 1]
, e poiché si fa l'interpolazione lineare in definitiva tra i prodotti punto, non significa che il valore finale sarà, a volte, essere al di fuori dell'intervallo [-1, 1]
?
Diciamo, per esempio, che uno dei vettori casuali è (sqrt(2)/2, sqrt(2)/2)
(che ha una lunghezza di 1) e (0.8, 0.8)
(che si trova nella piazza unità), si ottiene un risultato di circa 1.131
. Se tale valore viene utilizzato nell'interpolazione lineare, è del tutto possibile che il valore generato sia maggiore di 1
. E, in effetti, con la mia implementazione diretta, ciò accade abbastanza frequentemente.
Mi manca qualcosa qui?
Per riferimento, ecco il mio codice in Java. Vec
è una semplice classe per eseguire semplici aritmetiche vettoriali 2D, fade()
è la curva di facilità, lerp()
è l'interpolazione lineare e gradient(x, y)
fornisce il gradiente per tale punto di griglia come Vec
. La variabile gridSize
ti dà la dimensione della griglia in pixel (che è di tipo doppio):
public double getPoint(int x, int y) {
Vec p = new Vec(x/gridSize, y/gridSize);
Vec d = new Vec(Math.floor(p.x), Math.floor(p.y));
int x0 = (int)d.x,
y0 = (int)d.x;
double d00 = gradient(x0 , y0 ).dot(p.sub(x0 , y0 )),
d01 = gradient(x0 , y0 + 1).dot(p.sub(x0 , y0 + 1)),
d10 = gradient(x0 + 1, y0 ).dot(p.sub(x0 + 1, y0 )),
d11 = gradient(x0 + 1, y0 + 1).dot(p.sub(x0 + 1, y0 + 1));
double fadeX = fade(p.x - d.x),
fadeY = fade(p.y - d.y);
double i1 = lerp(fadeX, d00, d10),
i2 = lerp(fadeX, d01, d11);
return lerp(fadeY, i1, i2);
}
Edit: ecco il codice per la generazione di gradienti casuali:
double theta = gen.nextDouble() * 2 * Math.PI;
gradients[i] = new Vec(Math.cos(theta), Math.sin(theta));
Dove gen
è un java.util.Random
.
Grazie per il vostro aiuto! Questo l'ha risolto. – Oskar