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