001    package org.bukkit.util.noise;
002    
003    /**
004     * Creates noise using unbiased octaves
005     */
006    public abstract class OctaveGenerator {
007        protected final NoiseGenerator[] octaves;
008        protected double xScale = 1;
009        protected double yScale = 1;
010        protected double zScale = 1;
011    
012        protected OctaveGenerator(NoiseGenerator[] octaves) {
013            this.octaves = octaves;
014        }
015    
016        /**
017         * Sets the scale used for all coordinates passed to this generator.
018         * <p>
019         * This is the equivalent to setting each coordinate to the specified
020         * value.
021         *
022         * @param scale New value to scale each coordinate by
023         */
024        public void setScale(double scale) {
025            setXScale(scale);
026            setYScale(scale);
027            setZScale(scale);
028        }
029    
030        /**
031         * Gets the scale used for each X-coordinates passed
032         *
033         * @return X scale
034         */
035        public double getXScale() {
036            return xScale;
037        }
038    
039        /**
040         * Sets the scale used for each X-coordinates passed
041         *
042         * @param scale New X scale
043         */
044        public void setXScale(double scale) {
045            xScale = scale;
046        }
047    
048        /**
049         * Gets the scale used for each Y-coordinates passed
050         *
051         * @return Y scale
052         */
053        public double getYScale() {
054            return yScale;
055        }
056    
057        /**
058         * Sets the scale used for each Y-coordinates passed
059         *
060         * @param scale New Y scale
061         */
062        public void setYScale(double scale) {
063            yScale = scale;
064        }
065    
066        /**
067         * Gets the scale used for each Z-coordinates passed
068         *
069         * @return Z scale
070         */
071        public double getZScale() {
072            return zScale;
073        }
074    
075        /**
076         * Sets the scale used for each Z-coordinates passed
077         *
078         * @param scale New Z scale
079         */
080        public void setZScale(double scale) {
081            zScale = scale;
082        }
083    
084        /**
085         * Gets a clone of the individual octaves used within this generator
086         *
087         * @return Clone of the individual octaves
088         */
089        public NoiseGenerator[] getOctaves() {
090            return octaves.clone();
091        }
092    
093        /**
094         * Generates noise for the 1D coordinates using the specified number of
095         * octaves and parameters
096         *
097         * @param x X-coordinate
098         * @param frequency How much to alter the frequency by each octave
099         * @param amplitude How much to alter the amplitude by each octave
100         * @return Resulting noise
101         */
102        public double noise(double x, double frequency, double amplitude) {
103            return noise(x, 0, 0, frequency, amplitude);
104        }
105    
106        /**
107         * Generates noise for the 1D coordinates using the specified number of
108         * octaves and parameters
109         *
110         * @param x X-coordinate
111         * @param frequency How much to alter the frequency by each octave
112         * @param amplitude How much to alter the amplitude by each octave
113         * @param normalized If true, normalize the value to [-1, 1]
114         * @return Resulting noise
115         */
116        public double noise(double x, double frequency, double amplitude, boolean normalized) {
117            return noise(x, 0, 0, frequency, amplitude, normalized);
118        }
119    
120        /**
121         * Generates noise for the 2D coordinates using the specified number of
122         * octaves and parameters
123         *
124         * @param x X-coordinate
125         * @param y Y-coordinate
126         * @param frequency How much to alter the frequency by each octave
127         * @param amplitude How much to alter the amplitude by each octave
128         * @return Resulting noise
129         */
130        public double noise(double x, double y, double frequency, double amplitude) {
131            return noise(x, y, 0, frequency, amplitude);
132        }
133    
134        /**
135         * Generates noise for the 2D coordinates using the specified number of
136         * octaves and parameters
137         *
138         * @param x X-coordinate
139         * @param y Y-coordinate
140         * @param frequency How much to alter the frequency by each octave
141         * @param amplitude How much to alter the amplitude by each octave
142         * @param normalized If true, normalize the value to [-1, 1]
143         * @return Resulting noise
144         */
145        public double noise(double x, double y, double frequency, double amplitude, boolean normalized) {
146            return noise(x, y, 0, frequency, amplitude, normalized);
147        }
148    
149        /**
150         * Generates noise for the 3D coordinates using the specified number of
151         * octaves and parameters
152         *
153         * @param x X-coordinate
154         * @param y Y-coordinate
155         * @param z Z-coordinate
156         * @param frequency How much to alter the frequency by each octave
157         * @param amplitude How much to alter the amplitude by each octave
158         * @return Resulting noise
159         */
160        public double noise(double x, double y, double z, double frequency, double amplitude) {
161            return noise(x, y, z, frequency, amplitude, false);
162        }
163    
164        /**
165         * Generates noise for the 3D coordinates using the specified number of
166         * octaves and parameters
167         *
168         * @param x X-coordinate
169         * @param y Y-coordinate
170         * @param z Z-coordinate
171         * @param frequency How much to alter the frequency by each octave
172         * @param amplitude How much to alter the amplitude by each octave
173         * @param normalized If true, normalize the value to [-1, 1]
174         * @return Resulting noise
175         */
176        public double noise(double x, double y, double z, double frequency, double amplitude, boolean normalized) {
177            double result = 0;
178            double amp = 1;
179            double freq = 1;
180            double max = 0;
181    
182            x *= xScale;
183            y *= yScale;
184            z *= zScale;
185    
186            for (NoiseGenerator octave : octaves) {
187                result += octave.noise(x * freq, y * freq, z * freq) * amp;
188                max += amp;
189                freq *= frequency;
190                amp *= amplitude;
191            }
192    
193            if (normalized) {
194                result /= max;
195            }
196    
197            return result;
198        }
199    }