Created
May 10, 2021 10:05
-
-
Save jpcima/5aa61d5f591183fa8de7454db12324f6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define STB_IMAGE_WRITE_IMPLEMENTATION 1 | |
#include "stb_image_write.h" | |
#include <algorithm> | |
#include <random> | |
#include <cmath> | |
#include <cstdio> | |
#include <cstdint> | |
class BristolPRNG; | |
class fast_rand; | |
/// | |
using PRNG = BristolPRNG; | |
//using PRNG = fast_rand; | |
//using PRNG = std::minstd_rand0; | |
//using PRNG = std::default_random_engine; | |
/// | |
class BristolPRNG { | |
public: | |
uint32_t operator()() | |
{ | |
x1 ^= x2; | |
uint32_t next = x2; | |
x2 += x1; | |
return next; | |
} | |
private: | |
int x1 = 0x67452301; | |
int x2 = 0xefcdab89; | |
}; | |
/// other | |
class fast_rand { | |
public: | |
typedef uint32_t result_type; | |
fast_rand() noexcept | |
{ | |
seed(777); | |
} | |
explicit fast_rand(uint32_t value) noexcept | |
: mem(value) | |
{ | |
} | |
static constexpr uint32_t min() noexcept | |
{ | |
return 0; | |
} | |
static constexpr uint32_t max() noexcept | |
{ | |
return std::numeric_limits<uint32_t>::max(); | |
} | |
uint32_t operator()() noexcept | |
{ | |
uint32_t next = mem * 1664525u + 1013904223u; // Numerical Recipes | |
mem = next; | |
return next; | |
} | |
void seed(uint32_t value = 0) noexcept | |
{ | |
mem = value; | |
} | |
void discard(unsigned long long z) noexcept | |
{ | |
for (unsigned long long i = 0; i < z; ++i) | |
operator()(); | |
} | |
private: | |
uint32_t mem = 0; | |
}; | |
/// | |
int main() | |
{ | |
PRNG prng; | |
static constexpr int w = 512; | |
static constexpr int h = 512; | |
double* data = new double[w * h](); | |
// generate | |
static constexpr int n = 1024 * w * h; | |
for (int i = 0; i < n; ++i) { | |
uint32_t rnd = (uint32_t)prng(); | |
uint32_t slot = rnd % (uint32_t)(w * h); | |
data[slot] += 1; | |
} | |
// normalize to unity | |
double datamax = 0; | |
for (int i = 0; i < w * h; ++i) | |
datamax = std::max(data[i], datamax); | |
for (int i = 0; i < w * h; ++i) { | |
data[i] /= datamax; | |
} | |
// fill the pixels | |
uint8_t* buf = new uint8_t[4 * w * h](); | |
auto getpixel = [buf](int x, int y) -> uint8_t* { | |
return buf + 4 * x + 4 * w * y; | |
}; | |
// write pixels | |
for (int x = 0; x < w; ++x) { | |
for (int y = 0; y < h; ++y) { | |
uint8_t* pix = getpixel(x, y); | |
double value = data[x + y * w]; | |
uint8_t component = (uint8_t)std::lround(value * 0xff); | |
pix[0] = component; | |
pix[1] = component; | |
pix[2] = component; | |
pix[3] = 0xff; | |
} | |
} | |
// write image | |
stbi_write_png("randoms.png", w, h, 4, buf, 4 * w); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment