You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.3 KiB
110 lines
2.3 KiB
10 years ago
|
package mightypork.gamecore.util.math.noise;
|
||
10 years ago
|
|
||
|
|
||
|
/**
|
||
|
* 2D Perlin noise generator
|
||
|
*
|
||
|
* @author MightyPork
|
||
|
*/
|
||
|
public class NoiseGen {
|
||
|
|
||
|
private static final double lowBound = -0.7072;
|
||
|
private static final double highBound = 0.7072;
|
||
|
|
||
|
private final PerlinNoiseGenerator noiser;
|
||
|
|
||
|
private final double lowMul;
|
||
|
private final double highMul;
|
||
|
private final double middle;
|
||
|
private final double density;
|
||
|
|
||
|
|
||
10 years ago
|
/**
|
||
|
* make a new noise generator with a random seed
|
||
|
*
|
||
|
* @param density noise density (0..1). Lower density means larger "spots".
|
||
|
* @param low low bound ("valley")
|
||
|
* @param middle middle bound ("surface")
|
||
|
* @param high high bound ("hill")
|
||
|
*/
|
||
10 years ago
|
public NoiseGen(double density, double low, double middle, double high)
|
||
|
{
|
||
10 years ago
|
this(density, low, middle, high, Double.doubleToLongBits(Math.random()));
|
||
|
}
|
||
|
|
||
|
|
||
10 years ago
|
/**
|
||
|
* make a new noise generator
|
||
|
*
|
||
|
* @param density noise density (0..1). Lower density means larger "spots".
|
||
|
* @param low low bound ("valley")
|
||
|
* @param middle middle bound ("surface")
|
||
|
* @param high high bound ("hill")
|
||
|
* @param seed random seed to use
|
||
|
*/
|
||
10 years ago
|
public NoiseGen(double density, double low, double middle, double high, long seed)
|
||
|
{
|
||
10 years ago
|
if (low > middle || middle > high) throw new IllegalArgumentException("Invalid value range.");
|
||
|
|
||
|
this.density = density;
|
||
|
|
||
|
// norm low and high to be around zero
|
||
|
low -= middle;
|
||
|
high -= middle;
|
||
|
|
||
|
// scale
|
||
|
this.middle = middle;
|
||
|
|
||
|
lowMul = Math.abs(low / lowBound);
|
||
|
highMul = Math.abs(high / highBound);
|
||
|
|
||
|
noiser = new PerlinNoiseGenerator(seed);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Get value at coord
|
||
|
*
|
||
|
* @param x x coordinate
|
||
|
* @param y y coordinate
|
||
|
* @return value
|
||
|
*/
|
||
|
public double valueAt(double x, double y)
|
||
|
{
|
||
|
double raw = noiser.noise2(x * density, y * density);
|
||
|
|
||
|
if (raw < lowBound) {
|
||
|
raw = lowBound;
|
||
|
} else if (raw > highBound) {
|
||
|
raw = highBound;
|
||
|
}
|
||
|
|
||
|
if (raw < 0) {
|
||
|
return middle + lowMul * raw;
|
||
|
} else {
|
||
|
return middle + highMul * raw;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Build a map [height][width] of noise values
|
||
|
*
|
||
|
* @param width map width (number of columns)
|
||
|
* @param height map height (number of rows )
|
||
|
* @return the map
|
||
|
*/
|
||
|
public double[][] buildMap(int width, int height)
|
||
|
{
|
||
10 years ago
|
final double[][] map = new double[height][width];
|
||
10 years ago
|
|
||
|
for (int y = 0; y < height; y++) {
|
||
|
for (int x = 0; x < width; x++) {
|
||
|
map[y][x] = valueAt(x, y);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return map;
|
||
|
}
|
||
|
}
|