Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.Random;
- /**
- * A well documented Java implementation of Perlin Noise.
- *
- * @author Ramon Millsteed
- */
- public class PerlinNoise {
- /** The frequencies (2^i) for each octave. */
- private static int[] frequencies = new int[32];
- /** The permutations for the random gradient generator. */
- private static int[] permutations = new int[512];
- /**
- * Initialises the static frequency exponentials.
- */
- static {
- for (int i = 0; i < frequencies.length; i++) {
- frequencies[i] = (int) Math.pow(2, i);
- }
- }
- /**
- * Instantiates a new {@code PerlinNoise}.
- *
- * @param seed
- * The random number seed
- */
- public PerlinNoise(int seed) {
- Random random = new Random(seed);
- for (int i = 0; i < permutations.length / 2; i++) {
- permutations[256 + i] = permutations[i] = random.nextInt(256);
- }
- }
- /**
- * Returns a height value in a 3D plane using Perlin Noise with octave repetition.
- *
- * @param x
- * The x coordinate
- * @param y
- * The y coordinate
- * @param z
- * The z coordinate
- * @param octaves
- * The number of successive octaves
- * @return The height value
- */
- public float noise(float x, float y, float z, int octaves) {
- float height = 0.0f;
- for (int octave = 1; octave <= octaves; octave++) {
- int frequency = frequencies[octave];
- height += noise(x * frequency, y * frequency, z * frequency) / frequency;
- }
- return height;
- }
- /**
- * Returns a height value in a 3D plane using Perlin Noise without octave repetition.
- *
- * @param x
- * The x coordinate
- * @param y
- * The y coordinate
- * @param z
- * The z coordinate
- * @return The height value
- */
- public float noise(float x, float y, float z) {
- float fx = (float) Math.floor(x);
- float fy = (float) Math.floor(y);
- float fz = (float) Math.floor(z);
- int gx = (int) fx & 0xFF;
- int gy = (int) fy & 0xFF;
- int gz = (int) fz & 0xFF;
- float u = fade(x -= fx);
- float v = fade(y -= fy);
- float w = fade(z -= fz);
- int a0 = permutations[gx + 0] + gy;
- int b0 = permutations[gx + 1] + gy;
- int aa = permutations[a0 + 0] + gz;
- int ab = permutations[a0 + 1] + gz;
- int ba = permutations[b0 + 0] + gz;
- int bb = permutations[b0 + 1] + gz;
- float x2y2z2 = gradient(permutations[bb + 1], x - 1, y - 1, z - 1);
- float x1y2z2 = gradient(permutations[ab + 1], x - 0, y - 1, z - 1);
- float x2y1z2 = gradient(permutations[ba + 1], x - 1, y - 0, z - 1);
- float x1y1z2 = gradient(permutations[aa + 1], x - 0, y - 0, z - 1);
- float x2y2z1 = gradient(permutations[bb + 0], x - 1, y - 1, z - 0);
- float x1y2z1 = gradient(permutations[ab + 0], x - 0, y - 1, z - 0);
- float x2y1z1 = gradient(permutations[ba + 0], x - 1, y - 0, z - 0);
- float x1y1z1 = gradient(permutations[aa + 0], x - 0, y - 0, z - 0);
- float uInterpolatedY2Z2 = linearInterpolate(x1y2z2, x2y2z2, u);
- float uInterpolatedY1Z2 = linearInterpolate(x1y1z2, x2y1z2, u);
- float uInterpolatedY2Z1 = linearInterpolate(x1y2z1, x2y2z1, u);
- float uInterpolatedY1Z1 = linearInterpolate(x1y1z1, x2y1z1, u);
- float vInterpolatedZ1 = linearInterpolate(uInterpolatedY1Z1, uInterpolatedY2Z1, v);
- float vInterpolatedZ2 = linearInterpolate(uInterpolatedY1Z2, uInterpolatedY2Z2, v);
- return linearInterpolate(vInterpolatedZ1, vInterpolatedZ2, w);
- }
- /**
- * Finds the fade curve for a specified coordinate.
- *
- * @param coordinate
- * The decimal component of the coordinate
- * @return The fade curve
- */
- private float fade(float coordinate) {
- return (float) (Math.pow(coordinate, 3) * (coordinate * (coordinate * 6.0f - 15.0f) + 10.0f));
- }
- /**
- * Interpolates a value between two functions using a fade curve.
- *
- * @param a
- * The first function
- * @param b
- * The second function
- * @param fadeCurve
- * The coordinate fade curve
- * @return The interpolated value
- */
- private float linearInterpolate(float a, float b, float fadeCurve) {
- return a + fadeCurve * (b - a);
- }
- /**
- * Generates a random gradient using coordinates from a 3D plane.
- *
- * @param hash
- * The random hash permutation generated with a seed
- * @param x
- * The x coordinate
- * @param y
- * The y coordinate
- * @param z
- * The z coordinate
- * @return The random gradient
- */
- private float gradient(int hash, float x, float y, float z) {
- hash &= 15;
- float u = (hash < 8) ? x : y;
- float v = (hash < 4) ? y : ((hash == 12 || hash == 14) ? x : z);
- return ((hash & 1) == 0 ? u : -u) + ((hash & 2) == 0 ? v : -v);
- }
- }
Add Comment
Please, Sign In to add comment