Sic Semper Perlin Noise

/*

* RealPerlinNoise.h

*

* Created on: Aug 19, 2011

* Author: Mark Wazny

*/

#ifndef PERLINNOISE_H_

#define PERLINNOISE_H_

#include<stdlib.h>

#ifdef ANDROID

#define LAND_WIDTH 1024

#define LAND_LENGTH 512

#else

#define LAND_WIDTH 4096

#define LAND_LENGTH 2048

#endif

float ** GetEmptyArray(int width, int height) {

float ** array = (float **)malloc(width * sizeof(float *));

for(int k = 0; k < width; k++)

array[k] = (float *)malloc(height * sizeof(float));

return array;

}

float** GenerateWhiteNoise(int width, int height) {

float** noise = GetEmptyArray(width, height);

for (int i = 0; i < width; i++)

for (int j = 0; j < height; j++)

noise[i][j] = ((float)rand())/RAND_MAX;

return noise;

}

float Interpolate(float x0, float x1, float alpha) {

return x0 * (1 – alpha) + alpha * x1;

}

float GenerateSmoothNoise(float ** baseNoise, int i, int j, int octave) {

#ifndef ANDROID

int samplePeriod = 4*(1 << octave); // calculates 2 ^ k

#else

int samplePeriod = (1 << octave); // calculates 2 ^ k

#endif

float sampleFrequency = 1.0f / samplePeriod;

//calculate the horizontal sampling indices

int sample_i0 = (i / samplePeriod) * samplePeriod;

int sample_i1 = (sample_i0 + samplePeriod) % (LAND_WIDTH*2); //wrap around

float horizontal_blend = (i – sample_i0) * sampleFrequency;

//calculate the vertical sampling indices

int sample_j0 = (j / samplePeriod) * samplePeriod;

int sample_j1 = (sample_j0 + samplePeriod) % LAND_LENGTH; //wrap around

float vertical_blend = (j – sample_j0) * sampleFrequency;

//blend the top two corners

float top = Interpolate(baseNoise[sample_i0][sample_j0],

baseNoise[sample_i1][sample_j0], horizontal_blend);

//blend the bottom two corners

float bottom = Interpolate(baseNoise[sample_i0][sample_j1],

baseNoise[sample_i1][sample_j1], horizontal_blend);

//final blend

return Interpolate(top, bottom, vertical_blend);

}

void Gen(float **tmap) {

float ** whitenoise = GenerateWhiteNoise(LAND_WIDTH*2, LAND_LENGTH);

float ** tmap2 = GetEmptyArray(LAND_LENGTH, LAND_WIDTH);

int octaveCount = 9;

float persistance = 0.65f;

float amplitude = 1.0f;

float totalAmplitude = 0.0f;

for (int octave = octaveCount – 1; octave >= 0; octave–) {

amplitude *= persistance;

totalAmplitude += amplitude;

for (int i = 0; i < LAND_WIDTH; i++) {

for (int j = 0; j < LAND_LENGTH; j++) {

if(octave == octaveCount -1)

tmap[j][i] = 0;

tmap[j][i] += GenerateSmoothNoise(whitenoise, i+LAND_WIDTH, j, octave) * amplitude;

}

}

}

amplitude = 1.0f;

for (int octave = octaveCount – 1; octave >= 0; octave–) {

amplitude *= persistance;

for (int i = 0; i < LAND_WIDTH; i++) {

for (int j = 0; j < LAND_LENGTH; j++) {

if(octave == octaveCount -1)

tmap2[j][i] = 0;

tmap2[j][i] += GenerateSmoothNoise(whitenoise, i, j, octave) * amplitude;

}

}

}

for (int i = 0; i < LAND_WIDTH; i++)

for (int j = 0; j < LAND_LENGTH; j++)

tmap[j][i] = ((LAND_WIDTH – i) * tmap[j][i] + i * tmap2[j][i])/LAND_WIDTH/totalAmplitude;

for(int r = 0; r < LAND_WIDTH*2; r++) {

if(r < LAND_LENGTH)

free(tmap2[r]);

free(whitenoise[r]);

}

free(tmap2);

free(whitenoise);

}

#endif/* PERLINNOISE_H_ */

%d bloggers like this: