com.kenperlin.ImprovedNoise Maven / Gradle / Ivy
The newest version!
package com.kenperlin;
// JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN.
import java.io.Serializable;
import java.util.Random;
public final class ImprovedNoise implements Serializable {
public ImprovedNoise(long seed) {
int[] permutation = new int[256];
for (int i = 0; i < 256; i++) {
permutation[i] = i;
}
Random random = new Random(seed);
for (int i = 256; i > 1; i--) {
swap(permutation, i - 1, random.nextInt(i));
}
for (int i = 0; i < 256; i++) {
p[256 + i] = p[i] = permutation[i];
}
}
/**
* Output ranges:
*
*
* Dimensions Range
* 1 [-0.5, 0.5]
* 1 [-1.0, 1.0]
* 1 [-1.036353811211803, 1.036353811211803]*
*
*/
public double noise(double x, double y, double z) {
int X = (int) Math.floor(x) & 255, // FIND UNIT CUBE THAT
Y = (int) Math.floor(y) & 255, // CONTAINS POINT.
Z = (int) Math.floor(z) & 255;
x -= Math.floor(x); // FIND RELATIVE X,Y,Z
y -= Math.floor(y); // OF POINT IN CUBE.
z -= Math.floor(z);
double u = fade(x), // COMPUTE FADE CURVES
v = fade(y), // FOR EACH OF X,Y,Z.
w = fade(z);
int A = p[X ] + Y, AA = p[A] + Z, AB = p[A + 1] + Z, // HASH COORDINATES OF
B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; // THE 8 CUBE CORNERS,
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD
grad(p[BA ], x - 1, y , z )), // BLENDED
lerp(u, grad(p[AB ], x , y - 1, z ), // RESULTS
grad(p[BB ], x - 1, y - 1, z ))),// FROM 8
lerp(v, lerp(u, grad(p[AA + 1], x , y , z - 1), // CORNERS
grad(p[BA + 1], x - 1, y, z - 1)), // OF CUBE
lerp(u, grad(p[AB + 1], x , y - 1, z - 1),
grad(p[BB + 1], x - 1, y - 1, z - 1))));
}
private double fade(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
private double lerp(double t, double a, double b) {
return a + t * (b - a);
}
private double grad(int hash, double x, double y, double z) {
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
double u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
private void swap(int[] array, int index1, int index2) {
int tmp = array[index1];
array[index1] = array[index2];
array[index2] = tmp;
}
private final int p[] = new int[512];
private static final long serialVersionUID = 2011041301L;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy