/* Copyright (C) 2011 Garrett Fleenor
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or (at
your option) any later version.
This library 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 Lesser General Public
License (COPYING.txt) for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This is a port of libnoise ( http://libnoise.sourceforge.net/index.html ). Original implementation by Jason Bevins
*/
package com.bioxx.libnoise.module.source;
import com.bioxx.libnoise.MathHelper;
import com.bioxx.libnoise.Noise;
import com.bioxx.libnoise.Utils;
import com.bioxx.libnoise.module.Module;
public class Voronoi extends Module {
/// Default displacement to apply to each cell for the
/// noise::module::Voronoi noise module.
public static final double DEFAULT_VORONOI_DISPLACEMENT = 1.0;
/// Default frequency of the seed points for the noise::module::Voronoi
/// noise module.
public static final double DEFAULT_VORONOI_FREQUENCY = 1.0;
/// Default seed of the noise function for the noise::module::Voronoi
/// noise module.
public static final int DEFAULT_VORONOI_SEED = 0;
/// Scale of the random displacement to apply to each Voronoi cell.
double displacement = DEFAULT_VORONOI_DISPLACEMENT;
/// Determines if the distance from the nearest seed point is applied to
/// the output value.
boolean enableDistance = false;
/// Frequency of the seed points.
double frequency = DEFAULT_VORONOI_FREQUENCY;
/// Seed value used by the coherent-noise function to determine the
/// positions of the seed points.
int seed = DEFAULT_VORONOI_SEED;
public Voronoi() {
super(0);
}
public double getDisplacement() {
return displacement;
}
public void setDisplacement(double displacement) {
this.displacement = displacement;
}
public boolean isEnableDistance() {
return enableDistance;
}
public void setEnableDistance(boolean enableDistance) {
this.enableDistance = enableDistance;
}
public double getFrequency() {
return frequency;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
public int getSeed() {
return seed;
}
public void setSeed(int seed) {
this.seed = seed;
}
@Override
public int GetSourceModuleCount() {
return 0;
}
@Override
public double GetValue(double x, double y, double z) {
double x1 = x;
double y1 = y;
double z1 = z;
// This method could be more efficient by caching the seed values. Fix
// later.
x1 *= frequency;
y1 *= frequency;
z1 *= frequency;
int xInt = (x1 > 0.0 ? (int) x1 : (int) x1 - 1);
int yInt = (y1 > 0.0 ? (int) y1 : (int) y1 - 1);
int zInt = (z1 > 0.0 ? (int) z1 : (int) z1 - 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 + Noise.ValueNoise3D(xCur, yCur, zCur, seed);
double yPos = yCur + Noise.ValueNoise3D(xCur, yCur, zCur, seed + 1);
double zPos = zCur + Noise.ValueNoise3D(xCur, yCur, zCur, seed + 2);
double xDist = xPos - x1;
double yDist = yPos - y1;
double zDist = zPos - z1;
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 - x1;
double yDist = yCandidate - y1;
double zDist = zCandidate - z1;
value = (MathHelper.sqrt(xDist * xDist + yDist * yDist + zDist * zDist)) * Utils.SQRT_3 - 1.0;
} else {
value = 0.0;
}
// Return the calculated distance with the displacement value applied.
return value + (displacement * Noise.ValueNoise3D((int) (MathHelper.floor(xCandidate)), (int) (MathHelper.floor(yCandidate)), (int) (MathHelper.floor(zCandidate)), seed));
}
}