|
Packit Service |
2781ba |
/* Coherent noise function over 1, 2 or 3 dimensions */
|
|
Packit Service |
2781ba |
/* (copyright Ken Perlin) */
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "config.h"
|
|
Packit Service |
2781ba |
#include <stdlib.h>
|
|
Packit Service |
2781ba |
#include <stdio.h>
|
|
Packit Service |
2781ba |
#include <math.h>
|
|
Packit Service |
2781ba |
#include "perlin.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* random is not portable to all platforms */
|
|
Packit Service |
2781ba |
#define random g_random_int
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static int p[B + B + 2];
|
|
Packit Service |
2781ba |
static double g3[B + B + 2][3];
|
|
Packit Service |
2781ba |
static double g2[B + B + 2][2];
|
|
Packit Service |
2781ba |
static double g1[B + B + 2];
|
|
Packit Service |
2781ba |
static int start = 1;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
noise1 (double arg)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int bx0, bx1;
|
|
Packit Service |
2781ba |
double rx0, rx1, sx, t, u, v, vec[1];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
vec[0] = arg;
|
|
Packit Service |
2781ba |
if (start)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
start = 0;
|
|
Packit Service |
2781ba |
perlin_init ();
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
setup (0, bx0, bx1, rx0, rx1);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
sx = s_curve (rx0);
|
|
Packit Service |
2781ba |
u = rx0 * g1[p[bx0]];
|
|
Packit Service |
2781ba |
v = rx1 * g1[p[bx1]];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return (lerp (sx, u, v));
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
noise2 (double vec[2])
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int bx0, bx1, by0, by1, b00, b10, b01, b11;
|
|
Packit Service |
2781ba |
double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
|
|
Packit Service |
2781ba |
int i, j;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (start)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
start = 0;
|
|
Packit Service |
2781ba |
perlin_init ();
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
setup (0, bx0, bx1, rx0, rx1);
|
|
Packit Service |
2781ba |
setup (1, by0, by1, ry0, ry1);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
i = p[bx0];
|
|
Packit Service |
2781ba |
j = p[bx1];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
b00 = p[i + by0];
|
|
Packit Service |
2781ba |
b10 = p[j + by0];
|
|
Packit Service |
2781ba |
b01 = p[i + by1];
|
|
Packit Service |
2781ba |
b11 = p[j + by1];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
sx = s_curve (rx0);
|
|
Packit Service |
2781ba |
sy = s_curve (ry0);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g2[b00];
|
|
Packit Service |
2781ba |
u = at2 (rx0, ry0);
|
|
Packit Service |
2781ba |
q = g2[b10];
|
|
Packit Service |
2781ba |
v = at2 (rx1, ry0);
|
|
Packit Service |
2781ba |
a = lerp (sx, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g2[b01];
|
|
Packit Service |
2781ba |
u = at2 (rx0, ry1);
|
|
Packit Service |
2781ba |
q = g2[b11];
|
|
Packit Service |
2781ba |
v = at2 (rx1, ry1);
|
|
Packit Service |
2781ba |
b = lerp (sx, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return lerp (sy, a, b);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
noise3 (double vec[3])
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
|
|
Packit Service |
2781ba |
double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
|
|
Packit Service |
2781ba |
int i, j;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (start)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
start = 0;
|
|
Packit Service |
2781ba |
perlin_init ();
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
setup (0, bx0, bx1, rx0, rx1);
|
|
Packit Service |
2781ba |
setup (1, by0, by1, ry0, ry1);
|
|
Packit Service |
2781ba |
setup (2, bz0, bz1, rz0, rz1);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
i = p[bx0];
|
|
Packit Service |
2781ba |
j = p[bx1];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
b00 = p[i + by0];
|
|
Packit Service |
2781ba |
b10 = p[j + by0];
|
|
Packit Service |
2781ba |
b01 = p[i + by1];
|
|
Packit Service |
2781ba |
b11 = p[j + by1];
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
t = s_curve (rx0);
|
|
Packit Service |
2781ba |
sy = s_curve (ry0);
|
|
Packit Service |
2781ba |
sz = s_curve (rz0);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g3[b00 + bz0];
|
|
Packit Service |
2781ba |
u = at3 (rx0, ry0, rz0);
|
|
Packit Service |
2781ba |
q = g3[b10 + bz0];
|
|
Packit Service |
2781ba |
v = at3 (rx1, ry0, rz0);
|
|
Packit Service |
2781ba |
a = lerp (t, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g3[b01 + bz0];
|
|
Packit Service |
2781ba |
u = at3 (rx0, ry1, rz0);
|
|
Packit Service |
2781ba |
q = g3[b11 + bz0];
|
|
Packit Service |
2781ba |
v = at3 (rx1, ry1, rz0);
|
|
Packit Service |
2781ba |
b = lerp (t, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
c = lerp (sy, a, b);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g3[b00 + bz1];
|
|
Packit Service |
2781ba |
u = at3 (rx0, ry0, rz1);
|
|
Packit Service |
2781ba |
q = g3[b10 + bz1];
|
|
Packit Service |
2781ba |
v = at3 (rx1, ry0, rz1);
|
|
Packit Service |
2781ba |
a = lerp (t, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
q = g3[b01 + bz1];
|
|
Packit Service |
2781ba |
u = at3 (rx0, ry1, rz1);
|
|
Packit Service |
2781ba |
q = g3[b11 + bz1];
|
|
Packit Service |
2781ba |
v = at3 (rx1, ry1, rz1);
|
|
Packit Service |
2781ba |
b = lerp (t, u, v);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
d = lerp (sy, a, b);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return lerp (sz, c, d);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
normalize2 (double v[2])
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
double s;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
s = sqrt (v[0] * v[0] + v[1] * v[1]);
|
|
Packit Service |
2781ba |
v[0] = v[0] / s;
|
|
Packit Service |
2781ba |
v[1] = v[1] / s;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
normalize3 (double v[3])
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
double s;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
s = sqrt (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
Packit Service |
2781ba |
v[0] = v[0] / s;
|
|
Packit Service |
2781ba |
v[1] = v[1] / s;
|
|
Packit Service |
2781ba |
v[2] = v[2] / s;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
perlin_init (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int i, j, k;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < B; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
p[i] = i;
|
|
Packit Service |
2781ba |
g1[i] = (double) ((random () % (B + B)) - B) / B;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (j = 0; j < 2; j++)
|
|
Packit Service |
2781ba |
g2[i][j] = (double) ((random () % (B + B)) - B) / B;
|
|
Packit Service |
2781ba |
normalize2 (g2[i]);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (j = 0; j < 3; j++)
|
|
Packit Service |
2781ba |
g3[i][j] = (double) ((random () % (B + B)) - B) / B;
|
|
Packit Service |
2781ba |
normalize3 (g3[i]);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
while (--i)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
k = p[i];
|
|
Packit Service |
2781ba |
p[i] = p[j = random () % B];
|
|
Packit Service |
2781ba |
p[j] = k;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < B + 2; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
p[B + i] = p[i];
|
|
Packit Service |
2781ba |
g1[B + i] = g1[i];
|
|
Packit Service |
2781ba |
for (j = 0; j < 2; j++)
|
|
Packit Service |
2781ba |
g2[B + i][j] = g2[i][j];
|
|
Packit Service |
2781ba |
for (j = 0; j < 3; j++)
|
|
Packit Service |
2781ba |
g3[B + i][j] = g3[i][j];
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* --- My harmonic summing functions - PDB --------------------------*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/*
|
|
Packit Service |
2781ba |
In what follows "alpha" is the weight when the sum is formed.
|
|
Packit Service |
2781ba |
Typically it is 2, As this approaches 1 the function is noisier.
|
|
Packit Service |
2781ba |
"beta" is the harmonic scaling/spacing, typically 2.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
PerlinNoise1D (double x, double alpha, double beta, int n)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int i;
|
|
Packit Service |
2781ba |
double val, sum = 0;
|
|
Packit Service |
2781ba |
double p, scale = 1;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
p = x;
|
|
Packit Service |
2781ba |
for (i = 0; i < n; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
val = noise1 (p);
|
|
Packit Service |
2781ba |
sum += val / scale;
|
|
Packit Service |
2781ba |
scale *= alpha;
|
|
Packit Service |
2781ba |
p *= beta;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return (sum);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
PerlinNoise2D (double x, double y, double alpha, double beta, int n)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int i;
|
|
Packit Service |
2781ba |
double val, sum = 0;
|
|
Packit Service |
2781ba |
double p[2], scale = 1;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
p[0] = x;
|
|
Packit Service |
2781ba |
p[1] = y;
|
|
Packit Service |
2781ba |
for (i = 0; i < n; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
val = noise2 (p);
|
|
Packit Service |
2781ba |
sum += val / scale;
|
|
Packit Service |
2781ba |
scale *= alpha;
|
|
Packit Service |
2781ba |
p[0] *= beta;
|
|
Packit Service |
2781ba |
p[1] *= beta;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return (sum);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
double
|
|
Packit Service |
2781ba |
PerlinNoise3D (double x, double y, double z, double alpha, double beta, int n)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
int i;
|
|
Packit Service |
2781ba |
double val, sum = 0;
|
|
Packit Service |
2781ba |
double p[3], scale = 1.0;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (z < 0.0000)
|
|
Packit Service |
2781ba |
return PerlinNoise2D (x, y, alpha, beta, n);
|
|
Packit Service |
2781ba |
p[0] = x;
|
|
Packit Service |
2781ba |
p[1] = y;
|
|
Packit Service |
2781ba |
p[2] = z;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < n; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
val = noise3 (p);
|
|
Packit Service |
2781ba |
sum += val / scale;
|
|
Packit Service |
2781ba |
scale *= alpha;
|
|
Packit Service |
2781ba |
p[0] *= beta;
|
|
Packit Service |
2781ba |
p[1] *= beta;
|
|
Packit Service |
2781ba |
p[2] *= beta;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return (sum);
|
|
Packit Service |
2781ba |
}
|