/* This file was generated by scramble.py. */
#line 1 "src/voronoi.py"
#include "voronoi.h"
#line 2
#include "rgba.h"
#include "perlin.h"
#line 17
static float wrap_distance(float x1, float x2, float wrap) {
    /* |x1    x2             |x1
     * |x1              x2   |x1
     * |x2              x1   |x2
     */
#line 23
    float d = fabs(x2 - x1);
    float d2 = fabs(x1 + wrap - x2);
    if (d2 < d) {
#line 25
        d = d2;
    }
#line 26
    d2 = fabs(x2 + wrap - x1);
    if (d2 < d) {
#line 27
        d = d2;
    }
#line 28
    return d;
}
static int get_closest(Voronoi * self, int x, int y) {
    int mi = - 1;
    int md = INT_MAX;
    for (int i = 0; i < self->n; i += 1) {
        int dx = wrap_distance(self->xy [i].x, x, self->w);
        int dy = wrap_distance(self->xy [i].y, y, self->h);
        if (dx * dx + dy * dy < md) {
            mi = i;
            md = dx * dx + dy * dy;
        }
    }
#line 39
    return mi;
}
Voronoi * voronoi_create(int w, int h, int n, float randomness) {
    Voronoi * self;
#line 42
    land_alloc(self);
    self->w = w;
    self->h = h;
    self->map = land_calloc(w * h * sizeof (* self->map));
    self->distance = land_calloc(w * h * sizeof (* self->distance));
    self->n = n;
    self->xy = land_calloc(n * sizeof (* self->xy));
    self->max_distance = 0;
    int * map2 = land_calloc(w * h * sizeof (* map2));
#line 52
    for (int i = 0; i < n; i += 1) {
        int x = land_rand(0, w - 1);
        int y = land_rand(0, h - 1);
        self->xy [i].x = x;
        self->xy [i].y = y;
    }
    for (int y = 0; y < h; y += 1) {
        for (int x = 0; x < w; x += 1) {
            int i = get_closest(self, x, y);
            self->map [x + w * y] = i;
        }
    }
    // distort a bit
#line 64
    Perlin * perlin = perlin_create(w / 8, h / 8);
    for (int y = 0; y < h; y += 1) {
        for (int x = 0; x < w; x += 1) {
            float xd, yd;
            perlin_displace(perlin, x / 8.0, y / 8.0, & xd, & yd);
            int dx = imod(x + xd * randomness, self->w);
            int dy = imod(y + yd * randomness, self->h);
            int i = self->map [dx + w * dy];
            map2 [y * w + x] = i;
        }
    }
#line 73
    perlin_destroy(perlin);
#line 75
    land_free(self->map);
    self->map = map2;
#line 78
    for (int y = 0; y < h; y += 1) {
        for (int x = 0; x < w; x += 1) {
            int i = self->map [x + self->w * y];
            int dx = wrap_distance(self->xy [i].x, x, self->w);
            int dy = wrap_distance(self->xy [i].y, y, self->h);
            float d = sqrt(dx * dx + dy * dy);
            self->distance [x + self->w * y] = d;
            if (d > self->max_distance) {
                self->max_distance = d;
            }
        }
    }
#line 87
    return self;
}
void voronoi_destroy(Voronoi * self) {
    land_free(self->map);
    land_free(self->distance);
    land_free(self->xy);
    land_free(self);
}
float voronoi_at(Voronoi * self, int x, int y) {
    float value = self->distance [x + self->w * y] / self->max_distance;
    return value;
}
/* This file was generated by scramble.py. */
