From fd64e95a7ded219066f39b39dc96e1425e17c74b Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Thu, 17 May 2012 14:37:56 +1000 Subject: [PATCH] Expose the perlin class publically --- perlin.cpp | 140 ++++++++++++++++++++++++++--------------------------- perlin.hpp | 26 +++++++++- 2 files changed, 95 insertions(+), 71 deletions(-) diff --git a/perlin.cpp b/perlin.cpp index 5dfaf998..c5517264 100644 --- a/perlin.cpp +++ b/perlin.cpp @@ -34,78 +34,78 @@ #define LERP(a,b,t) lerp::quintic (a, b, t) -struct params { - typedef size_t seed_t; - - unsigned octaves; - double persistence; - double frequency; - seed_t seed; - - // Just a random generator [-1.0, 1.0] - double - generate (intmax_t x, intmax_t y) const { - intmax_t n = x + 257 * y; - n = (n << 13U) ^ n ^ (intmax_t)seed; - return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); - } - - double - eval (double x, double y) const { - intmax_t x_int = intmax_t (x); - double x_fac = x - x_int; - intmax_t y_int = intmax_t (y); - double y_fac = y - y_int; - - // Generate the four corner values - double p0 = generate (x_int, y_int); - double p1 = generate (x_int + 1, y_int); - double p2 = generate (x_int, y_int + 1); - double p3 = generate (x_int + 1, y_int + 1); - - // Interpolate on one dimension, then the other. - return LERP (LERP (p0, p1, x_fac), - LERP (p2, p3, x_fac), - y_fac); - } - - double - sample (double x, double y) const { - double total = 0.0; - - for (size_t i = 0; i < octaves; ++i) { - double f = frequency * powf (2.0, i); - double amplitude = powf (persistence, i); - - total += eval (x * f, y * f) * amplitude; - total = max (-1.0, min (1.0, total)); - } - - return (1.0 + total) / 2.0; - } - - params (): - octaves (3), - persistence (0.5), - frequency (25.0), - seed (util::random ()) - { ; } -}; - - -static void -perlin2d (uint8_t *restrict pixels, size_t width, size_t height, const params& p) { - for (size_t y = 0; y < height; ++y) - for (size_t x = 0; x < width; ++x) { - double v = p.sample (x / double (width), y / double (height)); /*perlin2d (x / double (width), - y / double (height), - (size_t)pixels);*/ - pixels[x + y * width] = v * std::numeric_limits::max (); - } +// Just a random generator [-1.0, 1.0] +double +util::perlin::generate (intmax_t x, intmax_t y) const { + intmax_t n = x + 257 * y; + n = (n << 13U) ^ n ^ (intmax_t)seed; + return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); } +double +util::perlin::eval (double x, double y) const { + intmax_t x_int = intmax_t (x); + double x_fac = x - x_int; + intmax_t y_int = intmax_t (y); + double y_fac = y - y_int; + + // Generate the four corner values + double p0 = generate (x_int, y_int); + double p1 = generate (x_int + 1, y_int); + double p2 = generate (x_int, y_int + 1); + double p3 = generate (x_int + 1, y_int + 1); + + // Interpolate on one dimension, then the other. + return LERP (LERP (p0, p1, x_fac), + LERP (p2, p3, x_fac), + y_fac); +} + + +double +util::perlin::sample (double x, double y) const { + double total = 0.0; + + for (size_t i = 0; i < octaves; ++i) { + double f = frequency * powf (2.0, i); + double amplitude = powf (persistence, i); + + total += eval (x * f, y * f) * amplitude; + total = max (-1.0, min (1.0, total)); + } + + return (1.0 + total) / 2.0; +} + + +util::perlin::perlin (): + octaves (3), + frequency (25.0), + persistence (0.5), + seed (util::random ()) +{ ; } + + +util::perlin::perlin (unsigned _octaves, + double _frequency, + double _persistence, + seed_t _seed): + octaves (_octaves), + frequency (_frequency), + persistence (_persistence), + seed (_seed) +{ ; } + + void -perlin2d (uint8_t *restrict pixels, size_t width, size_t height) { - perlin2d (pixels, width, height, params ()); +util::perlin2d (uint8_t *restrict pixels, + size_t width, + size_t height, + const perlin &p) { + for (size_t y = 0; y < height; ++y) + for (size_t x = 0; x < width; ++x) { + double v = p.sample (x / double (width), y / double (height)); + pixels[x + y * width] = v * std::numeric_limits::max (); + } } diff --git a/perlin.hpp b/perlin.hpp index c3b78ba1..0968d722 100644 --- a/perlin.hpp +++ b/perlin.hpp @@ -24,6 +24,30 @@ #include -void perlin2d (uint8_t *restrict pixels, size_t width, size_t height); +namespace util { + struct perlin { + typedef size_t seed_t; + + unsigned octaves; + double frequency; + double persistence; + seed_t seed; + + perlin (); + perlin (unsigned octaves, + double frequency, + double persistence, + seed_t seed); + + double sample (double x, double y) const; + + protected: + double generate (intmax_t x, intmax_t y) const; + double eval (double x, double y) const; + }; + + void perlin2d (uint8_t *restrict pixels, size_t width, size_t height, const perlin&); +} + #endif