ich ein paar der verschiedenen Implementierungen für kohärentes Rauschen zu untersuchen (ich weiß, es gibt Bibliotheken, aber dies ist vor allem für meine eigene Erbauung und Neugier) und wie Sie es verwenden können, und es gibt ein Problem Ich habe mit dem originalen Perlin Geräusch Ding.Ausgangsbereich von Perlin Geräusch
Laut this frequently linked Math FAQ wird der Ausgabebereich zwischen -1
und 1
liegen, aber ich verstehe nicht, wie der Wert in diesem Bereich sein wird.
Wie ich es zu verstehen, ist der Algorithmus im Grunde das: jeden Gitterpunkt hat einen zugeordneten zufälligen Gradientenvektor Länge 1
. Dann berechnen Sie für jeden Punkt für alle vier umgebenden Gitterpunkte das Skalarprodukt des zufälligen Gradienten und den Vektor, der von diesem Gitterpunkt ausgeht. Dann verwenden Sie eine einfache Lockerungskurve und lineare Interpolation, um das auf einen Wert zu reduzieren.
Aber hier ist mein Problem: Diese Dot-Produkte werden gelegentlich außerhalb des Bereichs [-1, 1]
liegen, und da Sie die lineare Interpolation letztendlich zwischen den Punktprodukten durchführen, bedeutet das nicht, dass der endgültige Wert gelegentlich außerhalb des Bereichs von [-1, 1]
liegen?
sie beispielsweise an, dass eines des Zufallsvektoren ist (sqrt(2)/2, sqrt(2)/2)
(die eine Länge von 1 hat) und (0.8, 0.8)
(die in dem Einheitsquadrat ist), dann ein Ergebnis von etwa 1.131
erhalten. Wenn dieser Wert in der linearen Interpolation verwendet wird, ist es durchaus möglich, dass der generierte Wert größer als 1
ist. Und in der Tat passiert das mit meiner geradlinigen Implementierung ziemlich häufig.
Fehle ich hier etwas?
Als Referenz hier ist mein Code in Java. Vec
ist eine einfache Klasse, um einfache 2d Vektorarithmetik zu tun, fade()
ist die Leichtigkeitskurve, lerp()
ist lineare Interpolation und gradient(x, y)
gibt Ihnen den Gradienten für diesen Gitterpunkt als Vec
. Die gridSize
Variable Sie die Größe des Gitters in Pixel gibt (es hat Typ double):
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: Hier ist der Code für die Erzeugung der Zufalls Gradienten:
double theta = gen.nextDouble() * 2 * Math.PI;
gradients[i] = new Vec(Math.cos(theta), Math.sin(theta));
Wo gen
ist ein java.util.Random
.
Danke für Ihre Hilfe! Das hat es behoben. – Oskar