Normalise basis values and give expected bounds
This commit is contained in:
parent
aabbf231c5
commit
c354cf6ed6
@ -27,6 +27,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
using namespace util::noise;
|
||||
using util::range;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Generate a type from [-UNIT..UNIT]
|
||||
@ -82,10 +83,16 @@ value<L>::value (seed_t _seed):
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
value<L>::value ()
|
||||
value<L>::value ()
|
||||
{ ; }
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
range<double>
|
||||
value<L>::bounds (void) const
|
||||
{ return { -1.0, 1.0 }; }
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
double
|
||||
value<L>::eval (double x, double y) const {
|
||||
@ -117,11 +124,18 @@ gradient<L>::gradient (seed_t _seed):
|
||||
basis (_seed)
|
||||
{ ; }
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
gradient<L>::gradient ()
|
||||
{ ; }
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
range<double>
|
||||
gradient<L>::bounds (void) const
|
||||
{ return { -sqrt(2.0) / 2.0, sqrt (2.0) / 2.0 }; }
|
||||
|
||||
|
||||
template <lerp_function L>
|
||||
double
|
||||
gradient<L>::eval (double x, double y) const {
|
||||
@ -130,11 +144,13 @@ gradient<L>::eval (double x, double y) const {
|
||||
double x_fac = x - x_int;
|
||||
double y_fac = y - y_int;
|
||||
|
||||
// Generate the four corner values
|
||||
vector2 p0 = generate<vector2> (x_int, y_int, this->seed);
|
||||
vector2 p1 = generate<vector2> (x_int + 1, y_int, this->seed);
|
||||
vector2 p2 = generate<vector2> (x_int, y_int + 1, this->seed);
|
||||
vector2 p3 = generate<vector2> (x_int + 1, y_int + 1, this->seed);
|
||||
// Generate the four corner values. It's not strictly necessary to
|
||||
// normalise the values, but we get a more consistent and visually
|
||||
// appealing range of outputs with normalised values.
|
||||
vector2 p0 = generate<vector2> (x_int, y_int, this->seed).normalise ();
|
||||
vector2 p1 = generate<vector2> (x_int + 1, y_int, this->seed).normalise ();
|
||||
vector2 p2 = generate<vector2> (x_int, y_int + 1, this->seed).normalise ();
|
||||
vector2 p3 = generate<vector2> (x_int + 1, y_int + 1, this->seed).normalise ();
|
||||
|
||||
double v0 = p0.x * x_fac + p0.y * y_fac;
|
||||
double v1 = p1.x * (x_fac - 1.0) + p1.y * y_fac;
|
||||
@ -161,6 +177,11 @@ cellular::cellular ()
|
||||
{ ; }
|
||||
|
||||
|
||||
range<double>
|
||||
cellular::bounds (void) const
|
||||
{ return { 0.0, sqrt(2) }; }
|
||||
|
||||
|
||||
double
|
||||
cellular::eval (double x, double y) const {
|
||||
using util::point2;
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include "../lerp.hpp"
|
||||
#include "../range.hpp"
|
||||
|
||||
namespace util {
|
||||
namespace noise {
|
||||
@ -35,6 +36,8 @@ namespace util {
|
||||
virtual ~basis ();
|
||||
|
||||
seed_t seed;
|
||||
|
||||
virtual range<double> bounds (void) const = 0;
|
||||
virtual double eval (double x, double y) const = 0;
|
||||
};
|
||||
|
||||
@ -42,18 +45,24 @@ namespace util {
|
||||
template <lerp_function L> struct value : public basis {
|
||||
value (seed_t);
|
||||
value ();
|
||||
|
||||
virtual range<double> bounds (void) const;
|
||||
virtual double eval (double x, double y) const;
|
||||
};
|
||||
|
||||
template <lerp_function L> struct gradient : public basis {
|
||||
gradient (seed_t);
|
||||
gradient ();
|
||||
|
||||
virtual range<double> bounds (void) const;
|
||||
virtual double eval (double x, double y) const;
|
||||
};
|
||||
|
||||
struct cellular : public basis {
|
||||
cellular (seed_t);
|
||||
cellular ();
|
||||
|
||||
virtual range<double> bounds (void) const;
|
||||
virtual double eval (double x, double y) const;
|
||||
};
|
||||
}
|
||||
|
@ -58,13 +58,15 @@ double
|
||||
util::noise::fbm<B>::eval (double x, double y) const {
|
||||
double total = 0.0;
|
||||
double f = this->frequency;
|
||||
double a = this->lacunarity;
|
||||
double a = 1.0;
|
||||
double a_sum = 0.0;
|
||||
|
||||
for (size_t i = 0; i < this->octaves; ++i) {
|
||||
total += basis.eval (x * f, y * f) * a;
|
||||
total = max (-1.0, min (1.0, total));
|
||||
|
||||
f *= 2.0;
|
||||
|
||||
a_sum += a;
|
||||
a *= this->lacunarity;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user