001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.math;
018
019public class FBM implements Function2D {
020
021        protected float[] exponents;
022        protected float H;
023        protected float lacunarity;
024        protected float octaves;
025        protected Function2D basis;
026
027        public FBM(float H, float lacunarity, float octaves) {
028                this(H, lacunarity, octaves, new Noise());
029        }
030        
031        public FBM(float H, float lacunarity, float octaves, Function2D basis) {
032                this.H = H;
033                this.lacunarity = lacunarity;
034                this.octaves = octaves;
035                this.basis = basis;
036
037                exponents = new float[(int)octaves+1];
038                float frequency = 1.0f;
039                for (int i = 0; i <= (int)octaves; i++) {
040                        exponents[i] = (float)Math.pow(frequency, -H);
041                        frequency *= lacunarity;
042                }
043        }
044
045        public void setBasis(Function2D basis) {
046                this.basis = basis;
047        }
048
049        public Function2D getBasisType() {
050                return basis;
051        }
052
053        public float evaluate(float x, float y) {
054                float value = 0.0f;
055                float remainder;
056                int i;
057                
058                // to prevent "cascading" effects
059                x += 371;
060                y += 529;
061                
062                for (i = 0; i < (int)octaves; i++) {
063                        value += basis.evaluate(x, y) * exponents[i];
064                        x *= lacunarity;
065                        y *= lacunarity;
066                }
067
068                remainder = octaves - (int)octaves;
069                if (remainder != 0)
070                        value += remainder * basis.evaluate(x, y) * exponents[i];
071
072                return value;
073        }
074
075}