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

com.flowpowered.noise.Noise Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of Flow Noise, licensed under the MIT License (MIT).
 *
 * Copyright (c) 2013 Flow Powered 
 * Original libnoise in C++ by Jason Bevins 
 * jlibnoise Java port by Garrett Fleenor 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.flowpowered.noise;

public final class Noise {
    private static final int X_NOISE_GEN = 1619;
    private static final int Y_NOISE_GEN = 31337;
    private static final int Z_NOISE_GEN = 6971;
    private static final int SEED_NOISE_GEN = 1013;
    private static final int SHIFT_NOISE_GEN = 8;

    private Noise() {
    }

    /**
     * Generates a gradient-coherent-noise value from the coordinates of a three-dimensional input value.
     *
     * @param x The @a x coordinate of the input value.
     * @param y The @a y coordinate of the input value.
     * @param z The @a z coordinate of the input value.
     * @param seed The random number seed.
     * @param quality The quality of the coherent-noise.
     * @return The generated gradient-coherent-noise value.
     * 

* The return value ranges from -1.0 to +1.0. *

* For an explanation of the difference between gradient noise and value noise, see the comments for the GradientNoise3D() function. */ public static double gradientCoherentNoise3D(double x, double y, double z, int seed, NoiseQuality quality) { // Create a unit-length cube aligned along an integer boundary. This cube // surrounds the input point. int x0 = ((x > 0.0) ? (int) x : (int) x - 1); int x1 = x0 + 1; int y0 = ((y > 0.0) ? (int) y : (int) y - 1); int y1 = y0 + 1; int z0 = ((z > 0.0) ? (int) z : (int) z - 1); int z1 = z0 + 1; // Map the difference between the coordinates of the input value and the // coordinates of the cube's outer-lower-left vertex onto an S-curve. double xs, ys, zs; if (quality == NoiseQuality.FAST) { xs = (x - (double) x0); ys = (y - (double) y0); zs = (z - (double) z0); } else if (quality == NoiseQuality.STANDARD) { xs = Utils.sCurve3(x - (double) x0); ys = Utils.sCurve3(y - (double) y0); zs = Utils.sCurve3(z - (double) z0); } else { xs = Utils.sCurve5(x - (double) x0); ys = Utils.sCurve5(y - (double) y0); zs = Utils.sCurve5(z - (double) z0); } // Now calculate the noise values at each vertex of the cube. To generate // the coherent-noise value at the input point, interpolate these eight // noise values using the S-curve value as the interpolant (trilinear // interpolation.) double n0, n1, ix0, ix1, iy0, iy1; n0 = gradientNoise3D(x, y, z, x0, y0, z0, seed); n1 = gradientNoise3D(x, y, z, x1, y0, z0, seed); ix0 = Utils.linearInterp(n0, n1, xs); n0 = gradientNoise3D(x, y, z, x0, y1, z0, seed); n1 = gradientNoise3D(x, y, z, x1, y1, z0, seed); ix1 = Utils.linearInterp(n0, n1, xs); iy0 = Utils.linearInterp(ix0, ix1, ys); n0 = gradientNoise3D(x, y, z, x0, y0, z1, seed); n1 = gradientNoise3D(x, y, z, x1, y0, z1, seed); ix0 = Utils.linearInterp(n0, n1, xs); n0 = gradientNoise3D(x, y, z, x0, y1, z1, seed); n1 = gradientNoise3D(x, y, z, x1, y1, z1, seed); ix1 = Utils.linearInterp(n0, n1, xs); iy1 = Utils.linearInterp(ix0, ix1, ys); return Utils.linearInterp(iy0, iy1, zs); } /** * Generates a gradient-noise value from the coordinates of a three-dimensional input value and the integer coordinates of a nearby three-dimensional value. * * @param fx The floating-point @a x coordinate of the input value. * @param fy The floating-point @a y coordinate of the input value. * @param fz The floating-point @a z coordinate of the input value. * @param ix The integer @a x coordinate of a nearby value. * @param iy The integer @a y coordinate of a nearby value. * @param iz The integer @a z coordinate of a nearby value. * @param seed The random number seed. * @return The generated gradient-noise value. *

* The difference between fx and ix must be less than or equal to one. The difference between @a fy and @a iy must be less than or equal to one. The difference between @a fz and @a iz must be less * than or equal to one. *

* A gradient-noise function generates better-quality noise than a value-noise function. Most noise modules use gradient noise for this reason, although it takes much longer to * calculate. *

* The return value ranges from -1.0 to +1.0. *

* This function generates a gradient-noise value by performing the following steps: - It first calculates a random normalized vector based on the nearby integer value passed to this function. - * It then calculates a new value by adding this vector to the nearby integer value passed to this function. - It then calculates the dot product of the above-generated value and the * floating-point input value passed to this function. *

* A noise function differs from a random-number generator because it always returns the same output value if the same input value is passed to it. */ public static double gradientNoise3D(double fx, double fy, double fz, int ix, int iy, int iz, int seed) { // Randomly generate a gradient vector given the integer coordinates of the // input value. This implementation generates a random number and uses it // as an index into a normalized-vector lookup table. int vectorIndex = (X_NOISE_GEN * ix + Y_NOISE_GEN * iy + Z_NOISE_GEN * iz + SEED_NOISE_GEN * seed); vectorIndex ^= (vectorIndex >> SHIFT_NOISE_GEN); vectorIndex &= 0xff; double xvGradient = Utils.randomVectors[(vectorIndex << 2)]; double yvGradient = Utils.randomVectors[(vectorIndex << 2) + 1]; double zvGradient = Utils.randomVectors[(vectorIndex << 2) + 2]; // Set up us another vector equal to the distance between the two vectors // passed to this function. double xvPoint = (fx - ix); double yvPoint = (fy - iy); double zvPoint = (fz - iz); // Now compute the dot product of the gradient vector with the distance // vector. The resulting value is gradient noise. Apply a scaling value // so that this noise value ranges from -1.0 to 1.0. return ((xvGradient * xvPoint) + (yvGradient * yvPoint) + (zvGradient * zvPoint)) * 2.12; } /** * Generates an integer-noise value from the coordinates of a three-dimensional input value. * * @param x The integer @a x coordinate of the input value. * @param y The integer @a y coordinate of the input value. * @param z The integer @a z coordinate of the input value. * @param seed A random number seed. * @return The generated integer-noise value. *

* The return value ranges from 0 to 2147483647. *

* A noise function differs from a random-number generator because it always returns the same output value if the same input value is passed to it. */ public static int intValueNoise3D(int x, int y, int z, int seed) { // All constants are primes and must remain prime in order for this noise // function to work correctly. int n = (X_NOISE_GEN * x + Y_NOISE_GEN * y + Z_NOISE_GEN * z + SEED_NOISE_GEN * seed) & 0x7fffffff; n = (n >> 13) ^ n; return (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; } /** * Generates a value-coherent-noise value from the coordinates of a three-dimensional input value. * * @param x The @a x coordinate of the input value. * @param y The @a y coordinate of the input value. * @param z The @a z coordinate of the input value. * @param seed The random number seed. * @param quality The quality of the coherent-noise. * @return The generated value-coherent-noise value. *

* The return value ranges from -1.0 to +1.0. *

* For an explanation of the difference between gradient noise and value noise, see the comments for the GradientNoise3D() function. */ public static double valueCoherentNoise3D(double x, double y, double z, int seed, NoiseQuality quality) { // Create a unit-length cube aligned along an integer boundary. This cube // surrounds the input point. int x0 = (x > 0.0 ? (int) x : (int) x - 1); int x1 = x0 + 1; int y0 = (y > 0.0 ? (int) y : (int) y - 1); int y1 = y0 + 1; int z0 = (z > 0.0 ? (int) z : (int) z - 1); int z1 = z0 + 1; // Map the difference between the coordinates of the input value and the // coordinates of the cube's outer-lower-left vertex onto an S-curve. double xs, ys, zs; if (quality == NoiseQuality.FAST) { xs = (x - x0); ys = (y - y0); zs = (z - z0); } else if (quality == NoiseQuality.STANDARD) { xs = Utils.sCurve3(x - x0); ys = Utils.sCurve3(y - y0); zs = Utils.sCurve3(z - z0); } else { xs = Utils.sCurve5(x - x0); ys = Utils.sCurve5(y - y0); zs = Utils.sCurve5(z - z0); } // Now calculate the noise values at each vertex of the cube. To generate // the coherent-noise value at the input point, interpolate these eight // noise values using the S-curve value as the interpolant (trilinear // interpolation.) double n0, n1, ix0, ix1, iy0, iy1; n0 = valueNoise3D(x0, y0, z0, seed); n1 = valueNoise3D(x1, y0, z0, seed); ix0 = Utils.linearInterp(n0, n1, xs); n0 = valueNoise3D(x0, y1, z0, seed); n1 = valueNoise3D(x1, y1, z0, seed); ix1 = Utils.linearInterp(n0, n1, xs); iy0 = Utils.linearInterp(ix0, ix1, ys); n0 = valueNoise3D(x0, y0, z1, seed); n1 = valueNoise3D(x1, y0, z1, seed); ix0 = Utils.linearInterp(n0, n1, xs); n0 = valueNoise3D(x0, y1, z1, seed); n1 = valueNoise3D(x1, y1, z1, seed); ix1 = Utils.linearInterp(n0, n1, xs); iy1 = Utils.linearInterp(ix0, ix1, ys); return Utils.linearInterp(iy0, iy1, zs); } /** * Generates a value-noise value from the coordinates of a three-dimensional input value. * * @param x The @a x coordinate of the input value. * @param y The @a y coordinate of the input value. * @param z The @a z coordinate of the input value. * @param seed A random number seed. * @return The generated value-noise value. *

* The return value ranges from -1.0 to +1.0. *

* A noise function differs from a random-number generator because it always returns the same output value if the same input value is passed to it. */ public static double valueNoise3D(int x, int y, int z, int seed) { return 1.0 - (intValueNoise3D(x, y, z, seed) / 1073741824.0); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy