Noise-1.0.0: libnoise/noise/src/module/voronoi.cpp
// voronoi.cpp
//
// Copyright (C) 2003, 2004 Jason Bevins
//
// 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 2.1 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
//
// The developer's email is jlbezigvins@gmzigail.com (for great email, take
// off every 'zig'.)
//
#include "../mathconsts.h"
#include "voronoi.h"
using namespace noise::module;
Voronoi::Voronoi ():
Module (GetSourceModuleCount ()),
m_displacement (DEFAULT_VORONOI_DISPLACEMENT),
m_enableDistance (false ),
m_frequency (DEFAULT_VORONOI_FREQUENCY ),
m_seed (DEFAULT_VORONOI_SEED )
{
}
double Voronoi::GetValue (double x, double y, double z) const
{
// This method could be more efficient by caching the seed values. Fix
// later.
x *= m_frequency;
y *= m_frequency;
z *= m_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 + ValueNoise3D (xCur, yCur, zCur, m_seed );
double yPos = yCur + ValueNoise3D (xCur, yCur, zCur, m_seed + 1);
double zPos = zCur + ValueNoise3D (xCur, yCur, zCur, m_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 (m_enableDistance) {
// Determine the distance to the nearest seed point.
double xDist = xCandidate - x;
double yDist = yCandidate - y;
double zDist = zCandidate - z;
value = (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 + (m_displacement * (double)ValueNoise3D (
(int)(floor (xCandidate)),
(int)(floor (yCandidate)),
(int)(floor (zCandidate))));
}