001    package org.bukkit.util.noise;
002    
003    /**
004     * Base class for all noise generators
005     */
006    public abstract class NoiseGenerator {
007        protected final int perm[] = new int[512];
008        protected double offsetX;
009        protected double offsetY;
010        protected double offsetZ;
011    
012        /**
013         * Speedy floor, faster than (int)Math.floor(x)
014         *
015         * @param x Value to floor
016         * @return Floored value
017         */
018        public static int floor(double x) {
019            return x >= 0 ? (int) x : (int) x - 1;
020        }
021    
022        protected static double fade(double x) {
023            return x * x * x * (x * (x * 6 - 15) + 10);
024        }
025    
026        protected static double lerp(double x, double y, double z) {
027            return y + x * (z - y);
028        }
029    
030        protected static double grad(int hash, double x, double y, double z) {
031            hash &= 15;
032            double u = hash < 8 ? x : y;
033            double v = hash < 4 ? y : hash == 12 || hash == 14 ? x : z;
034            return ((hash & 1) == 0 ? u : -u) + ((hash & 2) == 0 ? v : -v);
035        }
036    
037        /**
038         * Computes and returns the 1D noise for the given coordinate in 1D space
039         *
040         * @param x X coordinate
041         * @return Noise at given location, from range -1 to 1
042         */
043        public double noise(double x) {
044            return noise(x, 0, 0);
045        }
046    
047        /**
048         * Computes and returns the 2D noise for the given coordinates in 2D space
049         *
050         * @param x X coordinate
051         * @param y Y coordinate
052         * @return Noise at given location, from range -1 to 1
053         */
054        public double noise(double x, double y) {
055            return noise(x, y, 0);
056        }
057    
058        /**
059         * Computes and returns the 3D noise for the given coordinates in 3D space
060         *
061         * @param x X coordinate
062         * @param y Y coordinate
063         * @param z Z coordinate
064         * @return Noise at given location, from range -1 to 1
065         */
066        public abstract double noise(double x, double y, double z);
067    
068        /**
069         * Generates noise for the 1D coordinates using the specified number of
070         * octaves and parameters
071         *
072         * @param x X-coordinate
073         * @param octaves Number of octaves to use
074         * @param frequency How much to alter the frequency by each octave
075         * @param amplitude How much to alter the amplitude by each octave
076         * @return Resulting noise
077         */
078        public double noise(double x, int octaves, double frequency, double amplitude) {
079            return noise(x, 0, 0, octaves, frequency, amplitude);
080        }
081    
082        /**
083         * Generates noise for the 1D coordinates using the specified number of
084         * octaves and parameters
085         *
086         * @param x X-coordinate
087         * @param octaves Number of octaves to use
088         * @param frequency How much to alter the frequency by each octave
089         * @param amplitude How much to alter the amplitude by each octave
090         * @param normalized If true, normalize the value to [-1, 1]
091         * @return Resulting noise
092         */
093        public double noise(double x, int octaves, double frequency, double amplitude, boolean normalized) {
094            return noise(x, 0, 0, octaves, frequency, amplitude, normalized);
095        }
096    
097        /**
098         * Generates noise for the 2D coordinates using the specified number of
099         * octaves and parameters
100         *
101         * @param x X-coordinate
102         * @param y Y-coordinate
103         * @param octaves Number of octaves to use
104         * @param frequency How much to alter the frequency by each octave
105         * @param amplitude How much to alter the amplitude by each octave
106         * @return Resulting noise
107         */
108        public double noise(double x, double y, int octaves, double frequency, double amplitude) {
109            return noise(x, y, 0, octaves, frequency, amplitude);
110        }
111    
112        /**
113         * Generates noise for the 2D coordinates using the specified number of
114         * octaves and parameters
115         *
116         * @param x X-coordinate
117         * @param y Y-coordinate
118         * @param octaves Number of octaves to use
119         * @param frequency How much to alter the frequency by each octave
120         * @param amplitude How much to alter the amplitude by each octave
121         * @param normalized If true, normalize the value to [-1, 1]
122         * @return Resulting noise
123         */
124        public double noise(double x, double y, int octaves, double frequency, double amplitude, boolean normalized) {
125            return noise(x, y, 0, octaves, frequency, amplitude, normalized);
126        }
127    
128        /**
129         * Generates noise for the 3D coordinates using the specified number of
130         * octaves and parameters
131         *
132         * @param x X-coordinate
133         * @param y Y-coordinate
134         * @param z Z-coordinate
135         * @param octaves Number of octaves to use
136         * @param frequency How much to alter the frequency by each octave
137         * @param amplitude How much to alter the amplitude by each octave
138         * @return Resulting noise
139         */
140        public double noise(double x, double y, double z, int octaves, double frequency, double amplitude) {
141            return noise(x, y, z, octaves, frequency, amplitude, false);
142        }
143    
144        /**
145         * Generates noise for the 3D coordinates using the specified number of
146         * octaves and parameters
147         *
148         * @param x X-coordinate
149         * @param y Y-coordinate
150         * @param z Z-coordinate
151         * @param octaves Number of octaves to use
152         * @param frequency How much to alter the frequency by each octave
153         * @param amplitude How much to alter the amplitude by each octave
154         * @param normalized If true, normalize the value to [-1, 1]
155         * @return Resulting noise
156         */
157        public double noise(double x, double y, double z, int octaves, double frequency, double amplitude, boolean normalized) {
158            double result = 0;
159            double amp = 1;
160            double freq = 1;
161            double max = 0;
162    
163            for (int i = 0; i < octaves; i++) {
164                result += noise(x * freq, y * freq, z * freq) * amp;
165                max += amp;
166                freq *= frequency;
167                amp *= amplitude;
168            }
169    
170            if (normalized) {
171                result /= max;
172            }
173    
174            return result;
175        }
176    }