Added unbiased octave generators + normalized argument to generating noise through octaves

By: Dinnerbone <dinnerbone@dinnerbone.com>
This commit is contained in:
Bukkit/Spigot 2011-07-13 06:06:41 +01:00
parent fa0ea3b75c
commit 7bcdc12da0
5 changed files with 423 additions and 1 deletions

View File

@ -79,6 +79,20 @@ public abstract class NoiseGenerator {
return noise(x, 0, 0, octaves, frequency, amplitude); return noise(x, 0, 0, octaves, frequency, amplitude);
} }
/**
* Generates noise for the 1D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param octaves Number of octaves to use
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, int octaves, double frequency, double amplitude, boolean normalized) {
return noise(x, 0, 0, octaves, frequency, amplitude, normalized);
}
/** /**
* Generates noise for the 2D coordinates using the specified number of octaves and parameters * Generates noise for the 2D coordinates using the specified number of octaves and parameters
* *
@ -93,6 +107,21 @@ public abstract class NoiseGenerator {
return noise(x, y, 0, octaves, frequency, amplitude); return noise(x, y, 0, octaves, frequency, amplitude);
} }
/**
* Generates noise for the 2D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param octaves Number of octaves to use
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double y, int octaves, double frequency, double amplitude, boolean normalized) {
return noise(x, y, 0, octaves, frequency, amplitude, normalized);
}
/** /**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters * Generates noise for the 3D coordinates using the specified number of octaves and parameters
* *
@ -105,16 +134,38 @@ public abstract class NoiseGenerator {
* @return Resulting noise * @return Resulting noise
*/ */
public double noise(double x, double y, double z, int octaves, double frequency, double amplitude) { public double noise(double x, double y, double z, int octaves, double frequency, double amplitude) {
return noise(x, y, z, octaves, frequency, amplitude, false);
}
/**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @param octaves Number of octaves to use
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double y, double z, int octaves, double frequency, double amplitude, boolean normalized) {
double result = 0; double result = 0;
double amp = 1; double amp = 1;
double freq = 1; double freq = 1;
double max = 0;
for (int i = 0; i < octaves; i++) { for (int i = 0; i < octaves; i++) {
result += noise(x * freq, y * freq, z * freq) * amp; result += noise(x * freq, y * freq, z * freq) * amp;
max += amp;
freq *= frequency; freq *= frequency;
amp *= amplitude; amp *= amplitude;
} }
if (normalized) {
result /= max;
}
return result; return result;
} }
} }

View File

@ -0,0 +1,193 @@
package org.bukkit.util.noise;
/**
* Creates noise using unbiased octaves
*/
public abstract class OctaveGenerator {
protected final NoiseGenerator[] octaves;
protected double xScale = 1;
protected double yScale = 1;
protected double zScale = 1;
protected OctaveGenerator(NoiseGenerator[] octaves) {
this.octaves = octaves;
}
/**
* Sets the scale used for all coordinates passed to this generator.
*
* This is the equivalent to setting each coordinate to the specified value.
*
* @param scale New value to scale each coordinate by
*/
public void setScale(double scale) {
setXScale(scale);
setYScale(scale);
setZScale(scale);
}
/**
* Gets the scale used for each X-coordinates passed
*
* @return X scale
*/
public double getXScale() {
return xScale;
}
/**
* Sets the scale used for each X-coordinates passed
*
* @param scale New X scale
*/
public void setXScale(double scale) {
xScale = scale;
}
/**
* Gets the scale used for each Y-coordinates passed
*
* @return Y scale
*/
public double getYScale() {
return yScale;
}
/**
* Sets the scale used for each Y-coordinates passed
*
* @param scale New Y scale
*/
public void setYScale(double scale) {
yScale = scale;
}
/**
* Gets the scale used for each Z-coordinates passed
*
* @return Z scale
*/
public double getZScale() {
return zScale;
}
/**
* Sets the scale used for each Z-coordinates passed
*
* @param scale New Z scale
*/
public void setZScale(double scale) {
zScale = scale;
}
/**
* Gets a clone of the individual octaves used within this generator
*
* @return Clone of the individual octaves
*/
public NoiseGenerator[] getOctaves() {
return octaves.clone();
}
/**
* Generates noise for the 1D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @return Resulting noise
*/
public double noise(double x, double frequency, double amplitude) {
return noise(x, 0, 0, frequency, amplitude);
}
/**
* Generates noise for the 1D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double frequency, double amplitude, boolean normalized) {
return noise(x, 0, 0, frequency, amplitude, normalized);
}
/**
* Generates noise for the 2D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @return Resulting noise
*/
public double noise(double x, double y, double frequency, double amplitude) {
return noise(x, y, 0, frequency, amplitude);
}
/**
* Generates noise for the 2D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double y, double frequency, double amplitude, boolean normalized) {
return noise(x, y, 0, frequency, amplitude, normalized);
}
/**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @return Resulting noise
*/
public double noise(double x, double y, double z, double frequency, double amplitude) {
return noise(x, y, z, frequency, amplitude, false);
}
/**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double y, double z, double frequency, double amplitude, boolean normalized) {
double result = 0;
double amp = 1;
double freq = 1;
double max = 0;
x *= xScale;
y *= yScale;
z *= zScale;
for (int i = 0; i < octaves.length; i++) {
result += octaves[i].noise(x * freq, y * freq, z * freq) * amp;
max += amp;
freq *= frequency;
amp *= amplitude;
}
if (normalized) {
result /= max;
}
return result;
}
}

View File

@ -68,7 +68,7 @@ public class PerlinNoiseGenerator extends NoiseGenerator {
offsetZ = rand.nextDouble() * 256; offsetZ = rand.nextDouble() * 256;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
perm[i] = i; perm[i] = rand.nextInt(256);
} }
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {

View File

@ -0,0 +1,50 @@
package org.bukkit.util.noise;
import java.util.Random;
import org.bukkit.World;
/**
* Creates perlin noise through unbiased octaves
*/
public class PerlinOctaveGenerator extends OctaveGenerator {
/**
* Creates a perlin octave generator for the given world
*
* @param world World to construct this generator for
* @param octaves Amount of octaves to create
*/
public PerlinOctaveGenerator(World world, int octaves) {
this(new Random(world.getSeed()), octaves);
}
/**
* Creates a perlin octave generator for the given world
*
* @param seed Seed to construct this generator for
* @param octaves Amount of octaves to create
*/
public PerlinOctaveGenerator(long seed, int octaves) {
this(new Random(seed), octaves);
}
/**
* Creates a perlin octave generator for the given {@link Random}
*
* @param rand Random object to construct this generator for
* @param octaves Amount of octaves to create
*/
public PerlinOctaveGenerator(Random rand, int octaves) {
super(createOctaves(rand, octaves));
}
private static NoiseGenerator[] createOctaves(Random rand, int octaves) {
NoiseGenerator[] result = new NoiseGenerator[octaves];
for (int i = 0; i < octaves; i++) {
result[i] = new PerlinNoiseGenerator(rand);
}
return result;
}
}

View File

@ -0,0 +1,128 @@
package org.bukkit.util.noise;
import java.util.Random;
import org.bukkit.World;
/**
* Creates simplex noise through unbiased octaves
*/
public class SimplexOctaveGenerator extends OctaveGenerator {
private double wScale = 1;
/**
* Creates a simplex octave generator for the given world
*
* @param world World to construct this generator for
* @param octaves Amount of octaves to create
*/
public SimplexOctaveGenerator(World world, int octaves) {
this(new Random(world.getSeed()), octaves);
}
/**
* Creates a simplex octave generator for the given world
*
* @param seed Seed to construct this generator for
* @param octaves Amount of octaves to create
*/
public SimplexOctaveGenerator(long seed, int octaves) {
this(new Random(seed), octaves);
}
/**
* Creates a simplex octave generator for the given {@link Random}
*
* @param rand Random object to construct this generator for
* @param octaves Amount of octaves to create
*/
public SimplexOctaveGenerator(Random rand, int octaves) {
super(createOctaves(rand, octaves));
}
@Override
public void setScale(double scale) {
super.setScale(scale);
setWScale(scale);
}
/**
* Gets the scale used for each W-coordinates passed
*
* @return W scale
*/
public double getWScale() {
return wScale;
}
/**
* Sets the scale used for each W-coordinates passed
*
* @param scale New W scale
*/
public void setWScale(double scale) {
wScale = scale;
}
/**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @para, w W-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @return Resulting noise
*/
public double noise(double x, double y, double z, double w, double frequency, double amplitude) {
return noise(x, y, z, w, frequency, amplitude, false);
}
/**
* Generates noise for the 3D coordinates using the specified number of octaves and parameters
*
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @para, w W-coordinate
* @param frequency How much to alter the frequency by each octave
* @param amplitude How much to alter the amplitude by each octave
* @param normalized If true, normalize the value to [-1, 1]
* @return Resulting noise
*/
public double noise(double x, double y, double z, double w, double frequency, double amplitude, boolean normalized) {
double result = 0;
double amp = 1;
double freq = 1;
double max = 0;
x *= xScale;
y *= yScale;
z *= zScale;
w *= wScale;
for (int i = 0; i < octaves.length; i++) {
result += ((SimplexNoiseGenerator)octaves[i]).noise(x * freq, y * freq, z * freq, w * freq) * amp;
max += amp;
freq *= frequency;
amp *= amplitude;
}
if (normalized) {
result /= max;
}
return result;
}
private static NoiseGenerator[] createOctaves(Random rand, int octaves) {
NoiseGenerator[] result = new NoiseGenerator[octaves];
for (int i = 0; i < octaves; i++) {
result[i] = new SimplexNoiseGenerator(rand);
}
return result;
}
}