001package com.fs.starfarer.api.util;
002
003import java.util.Arrays;
004import java.util.Random;
005
006public class Noise {
007        public static Random random = new Random(Misc.genRandomSeed());
008        
009        public static float[] genNoise(int size, float spikes) {
010                float [] noise = new float[size];
011                Arrays.fill(noise, -1);
012                //noise[size/2] = 1f;
013//              noise[0] = 0f;
014//              noise[size - 1] = 0f;
015                noise[0] = 1f;
016                noise[size - 1] = 1f;
017                genNoise(noise, 0, size - 1, 1, spikes);
018                normalizeNoise(noise, 0, 1);
019                return noise;
020        }
021        
022        
023        public static void genNoise(float[] noise, int x1, int x2, int iter, float spikes) {
024                if (x1 + 1 >= x2)
025                        return; // no more values to fill
026
027                int midX = (x1 + x2) / 2;
028
029                fill(noise, midX, x1, x2, iter, spikes);
030                
031                genNoise(noise, x1, midX, iter + 1, spikes);
032                genNoise(noise, midX, x2, iter + 1, spikes);
033        }
034        
035        private static void normalizeNoise(float[] noise, float min, float max) {
036                float minNoise = Float.MAX_VALUE;
037                float maxNoise = -Float.MAX_VALUE;
038                for (int i = 0; i < noise.length; i++) {
039                        if (noise[i] == -1) continue;
040                        if (noise[i] > maxNoise) {
041                                maxNoise = noise[i];
042                        }
043                        if (noise[i] < minNoise) {
044                                minNoise = noise[i];
045                        }
046                }
047                if (minNoise >= maxNoise) return;
048
049                float range = maxNoise - minNoise;
050                for (int i = 0; i < noise.length; i++) {
051                        if (noise[i] != -1) {
052                                noise[i] = min + ((noise[i] - minNoise) / range * (max - min));
053                        } else {
054                                if (i > 0) {
055                                        noise[i] = noise[i - 1];
056                                } else if (i < noise.length - 1) {
057                                        noise[i] = noise[i + 1];
058                                } else {
059                                        noise[i] = .5f;
060                                }
061                        }
062                }
063        }
064        
065        private static void fill(float[] noise, int x, int x1, int x2, int iter, float spikes) {
066                if (noise[x] == -1) {
067                        float avg = (noise[x1] + noise[x2]) / 2f;
068                        noise[x] = avg + ((float) Math.pow(spikes, (iter)) * (float) (random.nextDouble() - .5f));
069                }
070        }
071}