/*
* Copyright (C) 2003, 2004 Jason Bevins (original libnoise code)
* Copyright 2010 Thomas J. Hodge (java port of libnoise)
*
* This file is part of libnoiseforjava.
*
* libnoiseforjava is a Java port of the C++ library libnoise, which may be found at
* http://libnoise.sourceforge.net/. libnoise was developed by Jason Bevins, who may be
* contacted at jlbezigvins@gmzigail.com (for great email, take off every 'zig').
* Porting to Java was done by Thomas Hodge, who may be contacted at
* libnoisezagforjava@gzagmail.com (remove every 'zag').
*
* libnoiseforjava is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* libnoiseforjava is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* libnoiseforjava. If not, see .
*
*/
package libnoiseforjava.module;
import libnoiseforjava.NoiseGen;
public class Voronoi extends ModuleBase
{
/// Noise module that outputs Voronoi cells.
///
/// In mathematics, a Voronoi cell is a region containing all the
/// points that are closer to a specific seed point than to any
/// other seed point. These cells mesh with one another, producing
/// polygon-like formations.
///
/// By default, this noise module randomly places a seed point within
/// each unit cube. By modifying the frequency of the seed points,
/// an application can change the distance between seed points. The
/// higher the frequency, the closer together this noise module places
/// the seed points, which reduces the size of the cells. To specify the
/// frequency of the cells, call the setFrequency() method.
///
/// This noise module assigns each Voronoi cell with a random constant
/// value from a coherent-noise function. The displacement value
/// controls the range of random values to assign to each cell. The
/// range of random values is +/- the displacement value. Call the
/// setDisplacement() method to specify the displacement value.
///
/// To modify the random positions of the seed points, call the SetSeed()
/// method.
///
/// This noise module can optionally add the distance from the nearest
/// seed to the output value. To enable this feature, call the
/// enableDistance() method. This causes the points in the Voronoi cells
/// to increase in value the further away that point is from the nearest
/// seed point.
///
/// Voronoi cells are often used to generate cracked-mud terrain
/// formations or crystal-like textures
///
/// This noise module requires no source modules.
/// Default displacement to apply to each cell for the
/// Voronoi noise module.
final static double DEFAULT_VORONOI_DISPLACEMENT = 1.0;
/// Default frequency of the seed points for the Voronoi
/// noise module.
final static double DEFAULT_VORONOI_FREQUENCY = 1.0;
/// Default seed of the noise function for the Voronoi
/// noise module.
final static int DEFAULT_VORONOI_SEED = 0;
private static final double SQRT_3 = 1.7320508075688772935;
/// Scale of the random displacement to apply to each Voronoi cell.
double displacement;
/// Determines if the distance from the nearest seed point is applied to
/// the output value.
boolean enableDistance;
/// Frequency of the seed points.
double frequency;
/// Seed value used by the coherent-noise function to determine the
/// positions of the seed points.
int seed;
public Voronoi ()
{
super(0);
displacement = DEFAULT_VORONOI_DISPLACEMENT;
enableDistance = false;
frequency = DEFAULT_VORONOI_FREQUENCY;
seed = DEFAULT_VORONOI_SEED;
}
public double getValue (double x, double y, double z)
{
// This method could be more efficient by caching the seed values. Fix
// later.
x *= frequency;
y *= frequency;
z *= frequency;
int xInt = (x > 0.0? (int)x: (int)x - 1);
int yInt = (y > 0.0? (int)y: (int)y - 1);
int zInt = (z > 0.0? (int)z: (int)z - 1);
double minDist = 2147483647.0;
double xCandidate = 0;
double yCandidate = 0;
double zCandidate = 0;
// Inside each unit cube, there is a seed point at a random position. Go
// through each of the nearby cubes until we find a cube with a seed point
// that is closest to the specified position.
for (int zCur = zInt - 2; zCur <= zInt + 2; zCur++)
{
for (int yCur = yInt - 2; yCur <= yInt + 2; yCur++)
{
for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++)
{
// Calculate the position and distance to the seed point inside of
// this unit cube.
double xPos = xCur + NoiseGen.ValueNoise3D (xCur, yCur, zCur, seed);
double yPos = yCur + NoiseGen.ValueNoise3D (xCur, yCur, zCur, seed + 1);
double zPos = zCur + NoiseGen.ValueNoise3D (xCur, yCur, zCur, seed + 2);
double xDist = xPos - x;
double yDist = yPos - y;
double zDist = zPos - z;
double dist = xDist * xDist + yDist * yDist + zDist * zDist;
if (dist < minDist)
{
// This seed point is closer to any others found so far, so record
// this seed point.
minDist = dist;
xCandidate = xPos;
yCandidate = yPos;
zCandidate = zPos;
}
}
}
}
double value;
if (enableDistance)
{
// Determine the distance to the nearest seed point.
double xDist = xCandidate - x;
double yDist = yCandidate - y;
double zDist = zCandidate - z;
value = (Math.sqrt(xDist * xDist + yDist * yDist + zDist * zDist)
) * SQRT_3 - 1.0;
} else {
value = 0.0;
}
// Return the calculated distance with the displacement value applied.
return value + (displacement * (double)NoiseGen.ValueNoise3D (
(int)(Math.floor (xCandidate)),
(int)(Math.floor (yCandidate)),
(int)(Math.floor (zCandidate)), seed));// added seed here, not in original
// but there isn't a working method
// without seed
}
/// Enables or disables applying the distance from the nearest seed
/// point to the output value.
///
/// @param enable Specifies whether to apply the distance to the
/// output value or not.
///
/// Applying the distance from the nearest seed point to the output
/// value causes the points in the Voronoi cells to increase in value
/// the further away that point is from the nearest seed point.
/// Setting this value to @a true (and setting the displacement to a
/// near-zero value) causes this noise module to generate cracked mud
/// formations.
public void enableDistance (boolean enable)
{
enableDistance = enable;
}
/// Returns the displacement value of the Voronoi cells.
///
/// @returns The displacement value of the Voronoi cells.
///
/// This noise module assigns each Voronoi cell with a random constant
/// value from a coherent-noise function. The displacement
/// value controls the range of random values to assign to each
/// cell. The range of random values is +/- the displacement value.
public double getDisplacement ()
{
return displacement;
}
/// Returns the frequency of the seed points.
///
/// @returns The frequency of the seed points.
///
/// The frequency determines the size of the Voronoi cells and the
/// distance between these cells.
public double GetFrequency ()
{
return frequency;
}
/// Returns the seed value used by the Voronoi cells
///
/// @returns The seed value.
///
/// The positions of the seed values are calculated by a
/// coherent-noise function. By modifying the seed value, the output
/// of that function changes.
public int getSeed ()
{
return seed;
}
/// Determines if the distance from the nearest seed point is applied
/// to the output value.
///
/// @returns
/// - @a true if the distance is applied to the output value.
/// - @a false if not.
///
/// Applying the distance from the nearest seed point to the output
/// value causes the points in the Voronoi cells to increase in value
/// the further away that point is from the nearest seed point.
public boolean IsDistanceEnabled ()
{
return enableDistance;
}
/// Sets the displacement value of the Voronoi cells.
///
/// @param displacement The displacement value of the Voronoi cells.
///
/// This noise module assigns each Voronoi cell with a random constant
/// value from a coherent-noise function. The displacement
/// value controls the range of random values to assign to each
/// cell. The range of random values is +/- the displacement value.
public void setDisplacement (double displacement)
{
this.displacement = displacement;
}
/// Sets the frequency of the seed points.
///
/// @param frequency The frequency of the seed points.
///
/// The frequency determines the size of the Voronoi cells and the
/// distance between these cells.
public void setFrequency (double frequency)
{
this.frequency = frequency;
}
/// Sets the seed value used by the Voronoi cells
///
/// @param seed The seed value.
///
/// The positions of the seed values are calculated by a
/// coherent-noise function. By modifying the seed value, the output
/// of that function changes.
public void setSeed (int seed)
{
this.seed = seed;
}
}