mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
Klasse für Perlin Noise implementiert
Die Klasse erzeugt Zuffalswerte nach dem von Ken Perlin erfundenen „Improved Perlin Noise“ Algorithmus.
This commit is contained in:
@@ -1327,7 +1327,7 @@ public class Constants {
|
|||||||
* @return Ein zufälliger Wert.
|
* @return Ein zufälliger Wert.
|
||||||
*/
|
*/
|
||||||
public static final double noise() {
|
public static final double noise() {
|
||||||
return getNoise().noise(N++);
|
return getNoise().noise(0.005 * N++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,304 +5,362 @@ import java.util.Random;
|
|||||||
/**
|
/**
|
||||||
* Zufallsgenerator für Perlin-Noise.
|
* Zufallsgenerator für Perlin-Noise.
|
||||||
* <p>
|
* <p>
|
||||||
* Die Implementierung basiert auf dem von Ken perlin entwickelten Algorithmus
|
* Die Implementierung basiert auf dem von Ken Perlin entwickelten Algorithmus
|
||||||
* und wurde von Matthew A. Johnston für Java implementiert.
|
* und wurde anhand der <a
|
||||||
* <p>
|
* href="https://adrianb.io/2014/08/09/perlinnoise.html">Beschreibung von
|
||||||
* Original KOmmentar:
|
* FLAFLA2</a> implementiert.
|
||||||
* <pre>
|
|
||||||
* This is Ken Perlin's implementation of Perlin Noise but modified to be more
|
|
||||||
* OOP.
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author Ken Perlin, Matthew A. Johnston (WarmWaffles)
|
|
||||||
*/
|
*/
|
||||||
public class Noise {
|
public class Noise {
|
||||||
|
|
||||||
private Random rand;
|
private static final int N = 256;
|
||||||
|
|
||||||
private static final int P = 8;
|
private static final int M = N - 1;
|
||||||
|
|
||||||
private static final int B = 1 << P;
|
|
||||||
|
|
||||||
private static final int M = B - 1;
|
|
||||||
|
|
||||||
private static final int NP = 8;
|
|
||||||
|
|
||||||
private static final int N = 1 << NP;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interne Permutationstabelle für diesen Generator
|
||||||
|
*/
|
||||||
private int[] p;
|
private int[] p;
|
||||||
|
|
||||||
private double[][] g2;
|
private double octaves = 1, persistence = .5;
|
||||||
|
|
||||||
private double[] g1;
|
private double frequency = 1;
|
||||||
|
|
||||||
private static double[][] points;
|
private double amplitude = 1;
|
||||||
|
|
||||||
|
private int repeat = -1;
|
||||||
|
|
||||||
|
private double rangeMin = 0.0, rangeMax = 1.0;
|
||||||
|
|
||||||
public Noise() {
|
public Noise() {
|
||||||
this(System.nanoTime());
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Noise( long seed ) {
|
public Noise( long seed ) {
|
||||||
this(new Random(seed));
|
init(new Random(seed));
|
||||||
}
|
|
||||||
|
|
||||||
public Noise( Random rand ) {
|
|
||||||
p = new int[B + B + 2];
|
|
||||||
g2 = new double[B + B + 2][2];
|
|
||||||
g1 = new double[B + B + 2];
|
|
||||||
|
|
||||||
points = new double[32][3];
|
|
||||||
|
|
||||||
this.rand = rand;
|
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A stub function that calls {@link #init()}
|
* Initialisiert diesen Perlin-Noise mit dem angegebenen Zufallsgenerator.
|
||||||
*
|
*
|
||||||
* @param seed
|
* @param rand
|
||||||
*/
|
*/
|
||||||
public void setSeed( int seed ) {
|
public Noise( Random rand ) {
|
||||||
this.rand = new Random(seed);
|
init(rand);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRandom( Random rand ) {
|
public double getOctaves() {
|
||||||
this.rand = rand;
|
return octaves;
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double noise( double x, double y, double z ) {
|
public void setOctaves( double pOctaves ) {
|
||||||
int bx, by, bz, b0, b1, b00, b10, b01, b11;
|
this.octaves = pOctaves;
|
||||||
double rx0, rx1, ry0, ry1, rz, sx, sy, sz, a, b, c, d, u, v, q[];
|
|
||||||
|
|
||||||
bx = (int) Math.IEEEremainder(Math.floor(x), B);
|
|
||||||
if( bx < 0 )
|
|
||||||
bx += B;
|
|
||||||
|
|
||||||
rx0 = x - Math.floor(x);
|
|
||||||
rx1 = rx0 - 1;
|
|
||||||
|
|
||||||
by = (int) Math.IEEEremainder(Math.floor(y), B);
|
|
||||||
if( by < 0 )
|
|
||||||
by += B;
|
|
||||||
|
|
||||||
ry0 = y - Math.floor(y);
|
|
||||||
ry1 = ry0 - 1;
|
|
||||||
|
|
||||||
bz = (int) Math.IEEEremainder(Math.floor(z), B);
|
|
||||||
if( bz < 0 )
|
|
||||||
bz += B;
|
|
||||||
|
|
||||||
rz = z - Math.floor(z);
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (bx < 0 || bx >= B + B + 2)
|
|
||||||
System.out.println(bx);
|
|
||||||
*/
|
|
||||||
b0 = p[bx];
|
|
||||||
|
|
||||||
bx++;
|
|
||||||
|
|
||||||
b1 = p[bx];
|
|
||||||
|
|
||||||
b00 = p[b0 + by];
|
|
||||||
b10 = p[b1 + by];
|
|
||||||
|
|
||||||
by++;
|
|
||||||
|
|
||||||
b01 = p[b0 + by];
|
|
||||||
b11 = p[b1 + by];
|
|
||||||
|
|
||||||
sx = s_curve(rx0);
|
|
||||||
sy = s_curve(ry0);
|
|
||||||
sz = s_curve(rz);
|
|
||||||
|
|
||||||
q = G(b00 + bz);
|
|
||||||
u = rx0 * q[0] + ry0 * q[1] + rz * q[2];
|
|
||||||
q = G(b10 + bz);
|
|
||||||
v = rx1 * q[0] + ry0 * q[1] + rz * q[2];
|
|
||||||
a = lerp(sx, u, v);
|
|
||||||
q = G(b01 + bz);
|
|
||||||
u = rx0 * q[0] + ry1 * q[1] + rz * q[2];
|
|
||||||
q = G(b11 + bz);
|
|
||||||
v = rx1 * q[0] + ry1 * q[1] + rz * q[2];
|
|
||||||
b = lerp(sx, u, v);
|
|
||||||
c = lerp(sy, a, b);
|
|
||||||
|
|
||||||
bz++;
|
|
||||||
rz--;
|
|
||||||
|
|
||||||
q = G(b00 + bz);
|
|
||||||
u = rx0 * q[0] + ry0 * q[1] + rz * q[2];
|
|
||||||
q = G(b10 + bz);
|
|
||||||
v = rx1 * q[0] + ry0 * q[1] + rz * q[2];
|
|
||||||
a = lerp(sx, u, v);
|
|
||||||
q = G(b01 + bz);
|
|
||||||
u = rx0 * q[0] + ry1 * q[1] + rz * q[2];
|
|
||||||
q = G(b11 + bz);
|
|
||||||
v = rx1 * q[0] + ry1 * q[1] + rz * q[2];
|
|
||||||
b = lerp(sx, u, v);
|
|
||||||
d = lerp(sy, a, b);
|
|
||||||
|
|
||||||
return lerp(sz, c, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double noise( double x, double y ) {
|
public double getPersistence() {
|
||||||
int bx0, bx1, by0, by1, b00, b10, b01, b11;
|
return persistence;
|
||||||
double rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v, q[];
|
}
|
||||||
int i, j;
|
|
||||||
|
|
||||||
t = x + N;
|
public void setPersistence( double pPersistence ) {
|
||||||
bx0 = ((int) t) & M;
|
this.persistence = pPersistence;
|
||||||
bx1 = (bx0 + 1) & M;
|
}
|
||||||
rx0 = t - (int) t;
|
|
||||||
rx1 = rx0 - 1;
|
|
||||||
|
|
||||||
t = y + N;
|
public double getFrequency() {
|
||||||
by0 = ((int) t) & M;
|
return frequency;
|
||||||
by1 = (by0 + 1) & M;
|
}
|
||||||
ry0 = t - (int) t;
|
|
||||||
ry1 = ry0 - 1;
|
|
||||||
|
|
||||||
i = p[bx0];
|
public void setFrequency( double pFrequency ) {
|
||||||
j = p[bx1];
|
this.frequency = pFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
b00 = p[i + by0];
|
public double getAmplitude() {
|
||||||
b10 = p[j + by0];
|
return amplitude;
|
||||||
b01 = p[i + by1];
|
}
|
||||||
b11 = p[j + by1];
|
|
||||||
|
|
||||||
sx = s_curve(rx0);
|
public void setAmplitude( double pAmplitude ) {
|
||||||
sy = s_curve(ry0);
|
this.amplitude = pAmplitude;
|
||||||
|
}
|
||||||
|
|
||||||
q = g2[b00];
|
public void setRange( double pRangeMin, double pRangeMax ) {
|
||||||
u = rx0 * q[0] + ry0 * q[1];
|
this.rangeMin = pRangeMin;
|
||||||
q = g2[b10];
|
this.rangeMax = pRangeMax;
|
||||||
v = rx1 * q[0] + ry0 * q[1];
|
}
|
||||||
a = lerp(sx, u, v);
|
|
||||||
|
|
||||||
q = g2[b01];
|
public double getRangeMin() {
|
||||||
u = rx0 * q[0] + ry1 * q[1];
|
return rangeMin;
|
||||||
q = g2[b11];
|
}
|
||||||
v = rx1 * q[0] + ry1 * q[1];
|
|
||||||
b = lerp(sx, u, v);
|
|
||||||
|
|
||||||
return lerp(sy, a, b);
|
public double getRangeMax() {
|
||||||
|
return rangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRepeat() {
|
||||||
|
return repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepeat( int pRepeat ) {
|
||||||
|
this.repeat = pRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double noise( double x ) {
|
public double noise( double x ) {
|
||||||
|
double total = 0;
|
||||||
|
double freq = this.frequency;
|
||||||
|
double amp = this.amplitude;
|
||||||
|
double maxValue = 0;
|
||||||
|
|
||||||
int bx0, bx1;
|
for( int i = 0; i < octaves; i++ ) {
|
||||||
double rx0, rx1, sx, t, u, v;
|
total += perlin(x * freq) * amp;
|
||||||
t = x + N;
|
|
||||||
bx0 = ((int) t) & M;
|
|
||||||
bx1 = (bx0 + 1) & M;
|
|
||||||
rx0 = t - (int) t;
|
|
||||||
rx1 = rx0 - 1;
|
|
||||||
|
|
||||||
sx = s_curve(rx0);
|
maxValue += amp;
|
||||||
u = rx0 * g1[p[bx0]];
|
|
||||||
v = rx1 * g1[p[bx1]];
|
|
||||||
|
|
||||||
return lerp(sx, u, v);
|
amp *= persistence;
|
||||||
|
freq *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lerp(rangeMin, rangeMax, (total / maxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
public double noise( double x, double y ) {
|
||||||
// PRIVATE
|
double total = 0;
|
||||||
// ========================================================================
|
double freq = this.frequency;
|
||||||
private void normalize2( double v[] ) {
|
double amp = this.amplitude;
|
||||||
double s;
|
double maxValue = 0;
|
||||||
s = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
|
|
||||||
v[0] = v[0] / s;
|
for( int i = 0; i < octaves; i++ ) {
|
||||||
v[1] = v[1] / s;
|
total += perlin(x * freq, y * freq) * amp;
|
||||||
|
|
||||||
|
maxValue += amp;
|
||||||
|
|
||||||
|
amp *= persistence;
|
||||||
|
freq *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lerp(rangeMin, rangeMax, (total / maxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double[] G( int i ) {
|
public double noise( double x, double y, double z ) {
|
||||||
return points[i % 32];
|
double total = 0;
|
||||||
|
double freq = this.frequency;
|
||||||
|
double amp = this.amplitude;
|
||||||
|
double maxValue = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i < octaves; i++ ) {
|
||||||
|
total += perlin(x * freq, y * freq, z * freq) * amp;
|
||||||
|
|
||||||
|
maxValue += amp;
|
||||||
|
|
||||||
|
amp *= persistence;
|
||||||
|
freq *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lerp(rangeMin, rangeMax, (total / maxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double s_curve( double t ) {
|
private double perlin( double x ) {
|
||||||
return t * t * (3 - t - t);
|
// @formatter:off
|
||||||
|
if( repeat > 0 ) {
|
||||||
|
x %= repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xi = (int)x & M;
|
||||||
|
|
||||||
|
double xf = x - (int)x;
|
||||||
|
|
||||||
|
double u = fade(xf);
|
||||||
|
|
||||||
|
int a, b;
|
||||||
|
a = p[ xi ];
|
||||||
|
b = p[inc(xi)];
|
||||||
|
|
||||||
|
return (lerp(grad(a,xf), grad(b,xf-1), u) + 1) / 2;
|
||||||
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
private double lerp( double t, double a, double b ) {
|
private double perlin( double x, double y ) {
|
||||||
|
// @formatter:off
|
||||||
|
if( repeat > 0 ) {
|
||||||
|
x %= repeat;
|
||||||
|
y %= repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xi = (int) x & M;
|
||||||
|
int yi = (int) y & M;
|
||||||
|
|
||||||
|
double xf = x - (int) x;
|
||||||
|
double yf = y - (int) y;
|
||||||
|
|
||||||
|
double u = fade(xf);
|
||||||
|
double v = fade(yf);
|
||||||
|
|
||||||
|
int aa, ab, ba, bb;
|
||||||
|
aa = p[p[ xi ] + yi ];
|
||||||
|
ab = p[p[ xi ] + inc(yi)];
|
||||||
|
ba = p[p[inc(xi)] + yi ];
|
||||||
|
bb = p[p[inc(xi)] + inc(yi)];
|
||||||
|
|
||||||
|
double x1, x2;
|
||||||
|
x1 = lerp(
|
||||||
|
grad(aa, xf , yf),
|
||||||
|
grad(ba, xf-1, yf),
|
||||||
|
u);
|
||||||
|
x2 = lerp(
|
||||||
|
grad(ab, xf , yf-1),
|
||||||
|
grad(bb, xf-1, yf-1),
|
||||||
|
u);
|
||||||
|
|
||||||
|
return (lerp(x1, x2, v) + 1) / 2;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
private double perlin( double x, double y, double z ) {
|
||||||
|
// @formatter:off
|
||||||
|
if( repeat > 0 ) {
|
||||||
|
x %= repeat;
|
||||||
|
y %= repeat;
|
||||||
|
z %= repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xi = (int)x & M;
|
||||||
|
int yi = (int)y & M;
|
||||||
|
int zi = (int)z & M;
|
||||||
|
double xf = x - (int)x;
|
||||||
|
double yf = y - (int)y;
|
||||||
|
double zf = z - (int)z;
|
||||||
|
|
||||||
|
double u = fade(xf);
|
||||||
|
double v = fade(yf);
|
||||||
|
double w = fade(zf);
|
||||||
|
|
||||||
|
int aaa, aba, aab, abb, baa, bba, bab, bbb;
|
||||||
|
aaa = p[p[p[ xi ] + yi ] + zi ];
|
||||||
|
aba = p[p[p[ xi ] + inc(yi)] + zi ];
|
||||||
|
aab = p[p[p[ xi ] + yi ] + inc(zi)];
|
||||||
|
abb = p[p[p[ xi ] + inc(yi)] + inc(zi)];
|
||||||
|
baa = p[p[p[inc(xi)] + yi ] + zi ];
|
||||||
|
bba = p[p[p[inc(xi)] + inc(yi)] + zi ];
|
||||||
|
bab = p[p[p[inc(xi)] + yi ] + inc(zi)];
|
||||||
|
bbb = p[p[p[inc(xi)] + inc(yi)] + inc(zi)];
|
||||||
|
|
||||||
|
double x1, x2, y1, y2;
|
||||||
|
x1 = lerp(
|
||||||
|
grad(aaa, xf , yf, zf),
|
||||||
|
grad(baa, xf-1, yf, zf),
|
||||||
|
u);
|
||||||
|
x2 = lerp(
|
||||||
|
grad(aba, xf , yf-1, zf),
|
||||||
|
grad(bba, xf-1, yf-1, zf),
|
||||||
|
u);
|
||||||
|
y1 = lerp(x1, x2, v);
|
||||||
|
|
||||||
|
x1 = lerp(
|
||||||
|
grad(aab, xf , yf, zf-1),
|
||||||
|
grad(bab, xf-1, yf, zf-1),
|
||||||
|
u);
|
||||||
|
x2 = lerp(
|
||||||
|
grad(abb, xf , yf-1, zf-1),
|
||||||
|
grad(bbb, xf-1, yf-1, zf-1),
|
||||||
|
u);
|
||||||
|
y2 = lerp(x1, x2, v);
|
||||||
|
|
||||||
|
return (lerp(y1, y2, w) + 1) / 2;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init( Random rand ) {
|
||||||
|
p = new int[N * 2];
|
||||||
|
|
||||||
|
if( rand == null ) {
|
||||||
|
System.arraycopy(PERLIN_PERMUTATION, 0, p, 0, N);
|
||||||
|
} else {
|
||||||
|
// Generate random permutation
|
||||||
|
for( int i = 0; i < N; i++ ) {
|
||||||
|
int n = rand.nextInt(N);
|
||||||
|
if( p[n] == 0 )
|
||||||
|
p[n] = i;
|
||||||
|
else
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate permutation array to prevent overflow errors
|
||||||
|
System.arraycopy(p, 0, p, N, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double fade( double t ) {
|
||||||
|
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double lerp( double a, double b, double t ) {
|
||||||
return a + t * (b - a);
|
return a + t * (b - a);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void init() {
|
private int inc( int i ) {
|
||||||
int i, j, k;
|
++i;
|
||||||
double u, v, w, U, V, W, Hi, Lo;
|
if( repeat > 0 )
|
||||||
|
i = i % repeat;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
for( i = 0; i < B; i++ ) {
|
private double grad( int hash, double x ) {
|
||||||
p[i] = i;
|
switch( hash & 0x1 ) {
|
||||||
g1[i] = 2 * rand.nextDouble() - 1;
|
// @formatter:off
|
||||||
|
case 0x0: return x;
|
||||||
do {
|
case 0x1: return -x;
|
||||||
u = 2 * rand.nextDouble() - 1;
|
default: return 0;
|
||||||
v = 2 * rand.nextDouble() - 1;
|
// @formatter:on
|
||||||
} while( u * u + v * v > 1 ||
|
|
||||||
Math.abs(u) > 2.5 * Math.abs(v) ||
|
|
||||||
Math.abs(v) > 2.5 * Math.abs(u) ||
|
|
||||||
Math.abs(Math.abs(u) - Math.abs(v)) < .4 );
|
|
||||||
|
|
||||||
g2[i][0] = u;
|
|
||||||
g2[i][1] = v;
|
|
||||||
|
|
||||||
normalize2(g2[i]);
|
|
||||||
|
|
||||||
do {
|
|
||||||
u = 2 * rand.nextDouble() - 1;
|
|
||||||
v = 2 * rand.nextDouble() - 1;
|
|
||||||
w = 2 * rand.nextDouble() - 1;
|
|
||||||
U = Math.abs(u);
|
|
||||||
V = Math.abs(v);
|
|
||||||
W = Math.abs(w);
|
|
||||||
Lo = Math.min(U, Math.min(V, W));
|
|
||||||
Hi = Math.max(U, Math.max(V, W));
|
|
||||||
} while( u * u + v * v + w * w > 1
|
|
||||||
|| Hi > 4 * Lo
|
|
||||||
|| Math.min(Math.abs(U - V),
|
|
||||||
Math.min(Math.abs(U - W), Math.abs(V - W))) < .2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
while( --i > 0 ) {
|
|
||||||
k = p[i];
|
|
||||||
j = (int) (rand.nextLong() & M);
|
|
||||||
p[i] = p[j];
|
|
||||||
p[j] = k;
|
|
||||||
}
|
|
||||||
for( i = 0; i < B + 2; i++ ) {
|
|
||||||
p[B + i] = p[i];
|
|
||||||
g1[B + i] = g1[i];
|
|
||||||
for( j = 0; j < 2; j++ )
|
|
||||||
g2[B + i][j] = g2[i][j];
|
|
||||||
}
|
|
||||||
|
|
||||||
points[3][0] = points[3][1] = points[3][2] = Math.sqrt(1. / 3);
|
|
||||||
double r2 = Math.sqrt(1. / 2);
|
|
||||||
double s = Math.sqrt(2 + r2 + r2);
|
|
||||||
|
|
||||||
for( i = 0; i < 3; i++ )
|
|
||||||
for( j = 0; j < 3; j++ )
|
|
||||||
points[i][j] = (i == j ? 1 + r2 + r2 : r2) / s;
|
|
||||||
|
|
||||||
|
|
||||||
for( i = 0; i <= 1; i++ ) {
|
|
||||||
for( j = 0; j <= 1; j++ ) {
|
|
||||||
for( k = 0; k <= 1; k++ ) {
|
|
||||||
int n = i + j * 2 + k * 4;
|
|
||||||
if( n > 0 ) {
|
|
||||||
for( int m = 0; m < 4; m++ ) {
|
|
||||||
points[4 * n + m][0] = (i == 0 ? 1 : -1) * points[m][0];
|
|
||||||
points[4 * n + m][1] = (j == 0 ? 1 : -1) * points[m][1];
|
|
||||||
points[4 * n + m][2] = (k == 0 ? 1 : -1) * points[m][2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private double grad( int hash, double x, double y ) {
|
||||||
|
switch( hash & 0x3 ) {
|
||||||
|
// @formatter:off
|
||||||
|
case 0x0: return x;
|
||||||
|
case 0x1: return -x;
|
||||||
|
case 0x2: return y;
|
||||||
|
case 0x3: return -y;
|
||||||
|
default: return 0;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double grad( int hash, double x, double y, double z ) {
|
||||||
|
switch( hash & 0xF ) {
|
||||||
|
// @formatter:off
|
||||||
|
case 0x0: return x + y;
|
||||||
|
case 0x1: return -x + y;
|
||||||
|
case 0x2: return x - y;
|
||||||
|
case 0x3: return -x - y;
|
||||||
|
case 0x4: return x + z;
|
||||||
|
case 0x5: return -x + z;
|
||||||
|
case 0x6: return x - z;
|
||||||
|
case 0x7: return -x - z;
|
||||||
|
case 0x8: return y + z;
|
||||||
|
case 0x9: return -y + z;
|
||||||
|
case 0xA: return y - z;
|
||||||
|
case 0xB: return -y - z;
|
||||||
|
case 0xC: return y + x;
|
||||||
|
case 0xD: return -y + z;
|
||||||
|
case 0xE: return y - x;
|
||||||
|
case 0xF: return -y - z;
|
||||||
|
default: return 0; // never happens
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int[] PERLIN_PERMUTATION = new int[]{
|
||||||
|
151, 160, 137, 91, 90, 15,
|
||||||
|
131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
|
||||||
|
190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
|
||||||
|
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
|
||||||
|
77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
|
||||||
|
102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
|
||||||
|
135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
|
||||||
|
5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
|
||||||
|
223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
|
||||||
|
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
|
||||||
|
251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
|
||||||
|
49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
|
||||||
|
138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/test/java/schule/ngb/zm/util/NoiseTest.java
Normal file
4
src/test/java/schule/ngb/zm/util/NoiseTest.java
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
class NoiseTest {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user