Mercurial > hg > dmlib
diff dmperlin.c @ 0:32250b436bca
Initial re-import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 28 Sep 2012 01:54:23 +0300 |
parents | |
children | 62f5861d332b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmperlin.c Fri Sep 28 01:54:23 2012 +0300 @@ -0,0 +1,136 @@ +/* + * Coherent noise function over 1 or 2 dimensions. + */ +#include "dmlib.h" +#include <math.h> + +#define B (0x100) +#define BM (0x0ff) +#define NP (12) +#define N (0x1000) +#define NM (0x0fff) + + +#define DM_PERLIN_SETUP(i, b0, b1, r0, r1) { \ + t = (vec[i] + N); \ + b0 = (((int) t) & BM); \ + b1 = ((b0 + 1) & BM); \ + r0 = (t - ((int) t)); \ + r1 = (r0 - 1.0f); \ + } + + +#define DM_PERLIN_AT2(rx,ry) ((rx) * q[0] + (ry) * q[1]) + + +static int p[B + B + 2]; +static DMFloat g2[B + B + 2][2]; +static DMFloat g1[B + B + 2]; + + +static DMFloat dmPerlinDoNoise2(DMFloat vec[2]) +{ + int bx0, bx1, by0, by1, b00, b10, b01, b11; + DMFloat rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v; + int i, j; + + DM_PERLIN_SETUP(0, bx0, bx1, rx0, rx1); + DM_PERLIN_SETUP(1, by0, by1, ry0, ry1); + + i = p[bx0]; + j = p[bx1]; + + b00 = p[i + by0]; + b10 = p[j + by0]; + b01 = p[i + by1]; + b11 = p[j + by1]; + + sx = DMM_S_CURVE(rx0); + sy = DMM_S_CURVE(ry0); + + q = g2[b00]; + u = DM_PERLIN_AT2(rx0, ry0); + q = g2[b10]; + v = DM_PERLIN_AT2(rx1, ry0); + a = DMM_LERP(sx, u, v); + + q = g2[b01]; + u = DM_PERLIN_AT2(rx0, ry1); + q = g2[b11]; + v = DM_PERLIN_AT2(rx1, ry1); + b = DMM_LERP(sx, u, v); + + return DMM_LERP(sy, a, b); +} + + +static void dmPerlinNormalize2(DMFloat v[2]) +{ + DMFloat s; + + s = sqrt(v[0] * v[0] + v[1] * v[1]); + + v[0] /= s; + v[1] /= s; +} + + +void dmPerlinInit(void) +{ + int i, j, k; + + srand(32); + + for (i = 0; i < B; i++) + { + p[i] = i; + g1[i] = (DMFloat) ((rand() % (B + B)) - B) / B; + + for (j = 0; j < 2; j++) + g2[i][j] = (DMFloat) ((rand() % (B + B)) - B) / B; + + dmPerlinNormalize2(g2[i]); + } + + while (--i) + { + k = p[i]; + p[i] = p[j = rand() % B]; + p[j] = k; + } + + for (i = 0; i < B + 2; i++) + { + p[B + i] = p[i]; + g1[B + i] = g1[i]; + + for (j = 0; j < 2; j++) + g2[B + i][j] = g2[i][j]; + } +} + + +/* Harmonic summing functions - PDB + * In what follows "alpha" is the weight when the sum is formed. + * Typically it is 2, As this approaches 1 the function is noisier. + * "beta" is the harmonic scaling/spacing, typically 2. + */ +DMFloat dmPerlinNoise2D(DMFloat x, DMFloat y, DMFloat alpha, DMFloat beta, int n) +{ + int i; + DMFloat val, sum = 0; + DMFloat p[2], scale = 1; + + p[0] = x; + p[1] = y; + for (i = 0; i < n; i++) + { + val = dmPerlinDoNoise2(p); + sum += val / scale; + scale *= alpha; + p[0] *= beta; + p[1] *= beta; + } + + return (sum); +}