Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Naive Voronoi generation writing out to P6 netpbm image.
- #include <limits.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- // Good random number generator xoroshiro64** 1.0
- // Written in 2018 by David Blackman and Sebastiano Vigna ([email protected])
- static inline uint32_t rotl(const uint32_t x, int k) {
- return (x << k) | (x >> (32 - k));
- }
- static uint32_t s[2];
- uint32_t next(void) {
- const uint32_t s0 = s[0];
- uint32_t s1 = s[1];
- const uint32_t result = rotl(s0 * 0x9E3779BB, 5) * 5;
- s1 ^= s0;
- s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
- s[1] = rotl(s1, 13); // c
- return result;
- }
- // End xoroshiro64** 1.0
- // Width and height of the Voronoi texture to be generated.
- #define height 512
- #define width 512
- #define NODE_COUNT 192
- typedef struct {
- int x;
- int y;
- } Node;
- Node nodes[NODE_COUNT] = {0};
- typedef struct {
- uint8_t r;
- uint8_t g;
- uint8_t b;
- } Pixel;
- Pixel palette[NODE_COUNT] = {0};
- int main() {
- // Set the seed for the RNG
- time_t t;
- time(&t);
- s[0] = (uint32_t)t;
- s[1] = (uint32_t)(t >> 32);
- // Allocate a pixel buffer to hold the image data.
- size_t nbytes = width * height * sizeof(Pixel);
- Pixel *pixels = calloc(width * height, sizeof(pixels[0]));
- if (!pixels) {
- fprintf(stderr, "ERROR: Failed to allocate %lu bytes for image buffer %d x %d\n", nbytes, width, height);
- return 1;
- }
- // Generate colors and node positions.
- int colorStep = 256 / NODE_COUNT;
- for (int i = 0; i < NODE_COUNT; ++i) {
- palette[i] = (Pixel){0, colorStep * i, colorStep * i >> 1};
- nodes[i].x = next() % width;
- nodes[i].y = next() % height;
- }
- // Iterate over each pixel in the buffer.
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- int closest = 0;
- int distance = INT_MAX;
- // Find the index of the closest Node.
- for (int i = 0; i < NODE_COUNT; ++i) {
- int dx = nodes[i].x - x;
- int dy = nodes[i].y - y;
- int distance_new = dx*dx + dy*dy;
- if (distance_new < distance) {
- closest = i;
- distance = distance_new;
- }
- }
- // Set the current pixel's color to the color of the closest Node.
- pixels[y * width + x] = palette[closest];
- }
- }
- // Write out the pixel data into the P6 netpbm image format.
- FILE *file = fopen("output.pbm", "wb");
- fprintf(file, "P6 %d %d 255 ", width, height);
- fwrite(pixels, sizeof(char), nbytes, file);
- fclose(file);
- return 0;
- }
Add Comment
Please, Sign In to add comment