001    /*
002    *
003    
004    Licensed under the Apache License, Version 2.0 (the "License");
005    you may not use this file except in compliance with the License.
006    You may obtain a copy of the License at
007    
008       http://www.apache.org/licenses/LICENSE-2.0
009    
010    Unless required by applicable law or agreed to in writing, software
011    distributed under the License is distributed on an "AS IS" BASIS,
012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    See the License for the specific language governing permissions and
014    limitations under the License.
015    */
016    
017    package railo.runtime.img.math;
018    
019    public 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    }