All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kenperlin.ImprovedNoise Maven / Gradle / Ivy

There is a newer version: 2.15.18
Show 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];
        }
    }

    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