## Heightmap Generation

### Noise Generation

Language: C++

This code sample demonstrate perlin noise generation. The final result is the sum of several coherent noises of varying frequencies and scale.

## Code sample

```namespace noiselib{

/**
* Return a value in a discrete 2D white noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
*/
double randNoiseDouble(int x, int y, int seed);

/**
* Return a value in a continuous 2D noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
* The function use a gradient method to generate noise which is spatially
* pseudo-uniform and coherent.
*/
double randGradientNoiseDouble(double x, double y, int seed);

/**
* Return a value in a 2D Perlin noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
* The function basically sum several gradient noise at different frequencies.
*/
double randPerlinNoise(double x, double y, int seed, int nbrOctave, double persistence);
}
```

### Implementation

```/**
* These constants are used by the randNoiseDouble function
*/
const int NOISE_P_X = 1619;
const int NOISE_P_Y = 31337;
const int NOISE_P_SEED = 1013;

/**
* A simple cos lookup table
*/
double cosValue[16] = {1.0,0.9238,0.7071,0.3826,0,-0.3826,-0.7071,-0.9238,
-1.0,-0.9238,-0.7071,-0.3826,0,0.3826,0.7071,0.9238};

/*
* The dot product of two vector
*/
double dotProduct(double vx, double vy, double wx, double wy){
return vx*wx+vy*wy;
}

/**
* A weigth function for polynomial interpolation
*/
double easeCurve(double t){
return 6*pow(t,5)-15*pow(t,4)+10*pow(t,3);
}

/**
* Linear interpolation between two value
*/
double linearInterpolation(double x0, double x1, double t){
return x0+(x1-x0)*t;
}

/**
* Interpolate between four values, using ease curves.
*/
double biLinearInterpolation(double x0y0, double x1y0, double x0y1, double x1y1, double x, double y){
double tx = easeCurve(x);
double ty = easeCurve(y);
double u = linearInterpolation(x0y0,x1y0,tx);
double v = linearInterpolation(x0y1,x1y1,tx);
return linearInterpolation(u,v,ty);
}

/**
* Return a value in a discrete 2D white noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
*/
double noiselib::randNoiseDouble(int x, int y, int seed){
int n = (
NOISE_P_X    * x
+ NOISE_P_Y    * y
+ NOISE_P_SEED * seed)
& 0x7fffffff;
n = (n >> 13) ^ n;
n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
return 1.0 - (double)n/1073741824;
}

/**
* Return a value in a continuous 2D noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
* The function use a gradient method to generate noise which is spatially
* pseudo-uniform and coherent.
*/
double noiselib::randGradientNoiseDouble(double x, double y, int seed){
//Get the top left border coordinate
int x0 = (x > 0.0? (int)x: (int)x - 1);
int y0 = (y > 0.0? (int)y: (int)y - 1);

//Local coordinate
double xl = x-x0;
double yl = y-y0;

//We associate a vector with each corner, by computing a random angle.
//We use an integer value in order to use the cos lookup table, cosValue.
//The vector are dependant of x and y. This is essential in order to obtain a coherent noise.
int n00 = (int)((randNoiseDouble(x0, y0, seed)+1)*8);
int n10 = (int)((randNoiseDouble(x0+1, y0, seed)+1)*8);
int n01 = (int)((randNoiseDouble(x0, y0+1, seed)+1)*8);
int n11 = (int)((randNoiseDouble(x0+1, y0+1, seed)+1)*8);

//Compute a value for each corner using dot product between the corner vectors and the local coordinates
double s = dotProduct(cosValue[n00], cosValue[(n00-4)%16], xl, yl);
double u = dotProduct(-cosValue[n10], cosValue[(n10-4)%16], 1.0-xl, yl);
double v = dotProduct(cosValue[n01], -cosValue[(n01-4)%16], xl, 1.0-yl);
double w = dotProduct(-cosValue[n11], -cosValue[(n11-4)%16], 1.0-xl, 1.0-yl);

//Interpolate the value
return biLinearInterpolation(s,u,v,w,xl,yl);
}

/**
* Return a value in a 2D Perlin noise given by seed at a particular coordinate.
* Consequently, the value is fully determined by x,y and seed.
* The function sum several gradient noise at different frequencies.
*/
double noiselib::randPerlinNoise(double x, double y, int seed, int nbrOctave, double persistence){
//We start from a 0 value.
double px = 0.0;