- A function to generate the world for the first time :

`void generate(int seed);`

- And a function you can run everytime you need to render or interact with terrain :

`double getAltitude(double longitude);`

- a RN Generator. I’m using the standard C++ library one :

`std::default_random_engine _rNGenerator;`

- an array of floats/doubles to store some random “noise” :

`QVector<double> _outline;`

(I’m using a custom class that comes with QtCreator but any standard C++ array will do the job).

- an integer to store the number of hills :

`int _nbHills;`

- a float or double to store the maximum altitude :

`double _mountainMaxHeight;`

- an integer to adjust the general smoothness of the terrain :

`int _smoothness;`

- a couple more double values that will store the coordinates of your “mountains” :

```
double _mountainOffset1;
double _mountainOffset2;
```

**Step 1.**

```
void World::generate(int seed){
_outline.clear(); //Or the standard C++ variant
_rNGenerator.seed(seed);
//Terrain features
std::uniform_real_distribution<double> terrainOutlineDistribution(0.0, 1.0);
std::uniform_int_distribution<> nbHillDistribution(0, 12);
std::uniform_real_distribution<double> mountainMaxHeightDistribution(MOUNTAIN_MIN_HEIGHT, MOUNTAIN_MAX_HEIGHT); //Set those as #defines
std::uniform_int_distribution<> smoothnessDistribution(MIN_SMOOTHNESS, MAX_SMOOTHNESS);
std::uniform_real_distribution<double> mountainOffsetDistribution(0.0, 2*PI);
```

**Step 2.**

```
int i;
for(i=0;i<360;i++)
{
_outline.push_back(terrainOutlineDistribution(_rNGenerator)); //Or standard C++ variant
}
_nbHills = nbHillDistribution(_rNGenerator);
_mountainMaxHeight = mountainMaxHeightDistribution(_rNGenerator);
_smoothness = smoothnessDistribution(_rNGenerator);
_mountainOffset1 = mountainOffsetDistribution(_rNGenerator);
_mountainOffset2 = mountainOffsetDistribution(_rNGenerator);
}
```

**Step 3.**

`double standardCoordinate(double longitude)`

```
double World::standardCoordinate(double coordinate)
{
//Converts coordinate in radians to an equivalent value within [0;2*PI[
double a = coordinate * 1000000;
double b = (2*PI) * 1000000;
a = int(a)%int(b);
b = a/1000000;
if(b<0.0)
b = (2*PI)+b;
return b;
}
```

```
double World::getAltitude(double longitude)
{
//longitude is converted to degrees
double location = (standardCoordinate(longitude)/(2*PI))*360.0;
double progressOnCurve = location - floor(location);
double minHeightFactor;
double maxHeightFactor;
double heightFactor;
if(floor(location) == 359) //This is for the last meridian of your world, that needs to be connected to the first
{
if(_outline[359]<=_outline[0]) //going uphill
{
if(progressOnCurve <= 0.5) //first half
{
maxHeightFactor = (_outline[359]+_outline[0])/2;
minHeightFactor = _outline[359];
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (1 - (sqrt((1-(2*progressOnCurve))) + (1 - sqrt((1-(2*progressOnCurve)))) * (1-(2*progressOnCurve))));
}
else //second half
{
maxHeightFactor = _outline[0];
minHeightFactor = (_outline[359]+_outline[0])/2;
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
*(sqrt(2*(progressOnCurve-0.5)) + (1 - sqrt(2*(progressOnCurve-0.5))) * (2*(progressOnCurve-0.5)));
}
}
else //going downhill
{
if(progressOnCurve <= 0.5) //first half
{
maxHeightFactor = _outline[359];
minHeightFactor = (_outline[359]+_outline[0])/2;
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (sqrt(1-(2*progressOnCurve)) + (1 - sqrt(1-(2*progressOnCurve))) * (1-(2*progressOnCurve)));
}
else //second half
{
maxHeightFactor = (_outline[359]+_outline[0])/2;
minHeightFactor = _outline[0];
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (1 - (sqrt(2*(progressOnCurve-0.5)) + (1 - sqrt(2*(progressOnCurve-0.5))) * (2*(progressOnCurve-0.5))));
}
}
}
else
{
if(_outline[floor(location)]<=_outline[floor(location)+1]) //going uphill
{
if(progressOnCurve <= 0.5) //first half
{
maxHeightFactor = (_outline[floor(location)]+_outline[floor(location)+1])/2;
minHeightFactor = _outline[floor(location)];
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (1 - (sqrt((1-(2*progressOnCurve))) + (1 - sqrt((1-(2*progressOnCurve)))) * (1-(2*progressOnCurve))));
}
else //second half
{
maxHeightFactor = _outline[floor(location)+1];
minHeightFactor = (_outline[floor(location)]+_outline[floor(location)+1])/2;
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
*(sqrt(2*(progressOnCurve-0.5)) + (1 - sqrt(2*(progressOnCurve-0.5))) * (2*(progressOnCurve-0.5)));
}
}
else //going downhill
{
if(progressOnCurve <= 0.5) //first half
{
maxHeightFactor = _outline[floor(location)];
minHeightFactor = (_outline[floor(location)]+_outline[floor(location)+1])/2;
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (sqrt(1-(2*progressOnCurve)) + (1 - sqrt(1-(2*progressOnCurve))) * (1-(2*progressOnCurve)));
}
else //second half
{
maxHeightFactor = (_outline[floor(location)]+_outline[floor(location)+1])/2;
minHeightFactor = _outline[floor(location)+1];
heightFactor = minHeightFactor + (maxHeightFactor-minHeightFactor)
* (1 - (sqrt(2*(progressOnCurve-0.5)) + (1 - sqrt(2*(progressOnCurve-0.5))) * (2*(progressOnCurve-0.5))));
}
}
}
```

**Step 4.**

```
double smoothness = _smoothness;
return (heightFactor/smoothness+((smoothness-1)/smoothness))
*((cos(longitude*_nbHills)+1)/8+0.75)
*((cos(longitude-_mountainOffset1)+1)/4+0.5)
*((cos(longitude-_mountainOffset2)+1)/4+0.5)
*_mountainMaxHeight;
}
```