001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.pub.noise.perlin;
011
012import imagingbook.pub.noise.hashing.HashFun;
013
014
015/**
016 * Gradient (Perlin) noise implementation. 
017 * This class implements a 1D Perlin noise generator.
018 */
019
020public class PerlinNoiseGen1d extends PerlinNoiseGen {
021        
022        public PerlinNoiseGen1d(double f_min, double f_max, double persistence, HashFun hf) {
023                super(f_min, f_max, persistence, hf);
024        }
025        
026        /**
027         * 1D combined (multi-frequency) Perlin noise function. 
028         * @param x Interpolation position.
029         * @return The value of the combined Perlin
030         * noise function for the one-dimensional position x.
031         */
032        public double NOISE(double x) {
033                double sum = 0;
034                for (int i=0; i<F.length; i++) {
035                        sum = sum + A[i] * noise(F[i] * x);
036                }
037                return sum;
038        }
039        
040        /**
041         * 1D elementary (single-frequency) Perlin noise function. 
042         * @param x Interpolation position.
043         * @return The value of the elementary Perlin
044         * noise function for the one-dimensional position x.
045         */
046        public double noise(double x) {
047                int p0 = ffloor(x);
048                double g0 = gradient(p0);
049                double g1 = gradient(p0 + 1);
050                double x01 = x - p0;
051                double w0 = g0 * x01;
052                double w1 = g1 * (x01 - 1);
053                return interpolate(x01, w0, w1);
054        }
055        
056        /**
057         * @param p discrete position.
058         * @return A pseudo-random gradient value for the discrete 
059         * position p.
060         */
061        double gradient(int p) {
062                return 2.0 * hashFun.hash(p) - 1;
063        }
064        
065        /**
066         * Local interpolation function.
067         * @param x01 The interpolation position in [0,1]
068         * @param w0 Tangent value for x=0.
069         * @param w1 Tangent value for x=1.
070         * @return The interpolated noise value at position x01.
071         */
072        double interpolate(double x01, double w0, double w1) { // local interpolation function (x01 is in [0,1])
073                double s = this.s(x01); 
074                return (1 - s) * w0 + s * w1;
075        }
076}