📜 ⬆️ ⬇️

Generate elevation map

C ++ is used as a programming language here, but it will not be very difficult to transfer this code to another programming language.
The code written below is far from ideal, but it can come in handy for beginners.
Not so long ago, I had a problem with generating a height map for a landscape.

I decided to try to set a random value for each point.


Here is a sample code for a two-dimensional array of data.

//      srand(GetTickCount()); for(int i=0;i<World::size;i++) { for(int u=0;u<World::size;u++) { //      0*0.1-10,  100*0.1-10 World::data[i][u]=(rand()%100)*0.1f-10.0f; } } 

')
But this result was no good for me, and I decided to add hills and pits.



Code using the Land_MakeHill function (the code of which is below):

 srand(GetTickCount()); for(int i=0;i<rand()%(World::size*World::size*1000);i++) { Land_MakeHill(World::data, //  rand()%(World::size), //  X     rand()%(World::size), //  Y     World::size, //  (rand()%20*1.0)+20)/100.0, //  rand()%14+14); // (    14  28 ). } srand(GetTickCount()); for(int i=0;i<rand()%(World::size*World::size*1000);i++) { Land_MakeHill(World::data, //  rand()%(World::size), //  X     rand()%(World::size), //  Y     World::size, //  -(rand()%20*1.0)+20)/100.0, //  rand()%4+7); // (    7  11 ). } 


Please note - the difference between creating a hill and a pit is only height. At the pit it is less than zero, at the hill it is more.
Land_MakeHill function code:

 /*data -   , px -   x, py -   y, size -  , height - , Rad -  */ void Land_MakeHill(float** data,int px,int pz, int size,float height,int Rad ) { for(int i=0;i<size;i++){ for(int w=0;w<size;w++){ //    ,    float d=Rad *Rad -((px-i)*(px-i)+(pz-w)*(pz-w)); data[i][w]+=d*height; } } } 


This landscape is not enough smoothness, so it took to make smoothing.



Land_blur function code:

 void Land_Blur(float** data,int size) { //   float** oldData = new float*[size]; for (int i = 0; i < size; i++){ oldData[i] = new float[size]; } //       ,         for(int i=0;i<size;i++){ for(int u=0;u<size;u++){ oldData[i][u]=data[i][u]; } } //      ,      8  . for(int i=1;i<size-1;i++){ for(int u=1;u<size-1;u++){ float v[9]; v[0]=data[i-1][u-1]; v[1]=data[i-1][u ]; v[2]=data[i-1][u+1]; v[3]=data[i] [u-1]; v[4]=data[i] [u ]; v[5]=data[i] [u+1]; v[6]=data[i+1][u-1]; v[7]=data[i+1][u ]; v[8]=data[i+1][u+1]; data[i][u]=(v[0]+v[1]+v[2]+v[3]+v[4]+v[5]+v[6]+v[7]+v[8])/9; } } } 


This is the simplest smoothing.
A point is taken, points around it are taken. Their values ​​are added and divided by their number.
This value is the height of the selected point.
Now the code for generating the height map is as follows:

  //      for(int i=0;i<World::size;i++) { for(int u=0;u<World::size;u++) { srand(GetTickCount()*i*u); World::data[i][u]=(rand()%1000)*0.1-100; } } srand(GetTickCount()); //  for(int i=0;i<rand()%(World::size*World::size*1000);i++) { //   ,     Land_MakeHill(World::data,rand()%(World::size*17),rand()%(World::size*17),World::size,((rand()%10*1.0)+10)/100.0,rand()%14+14); } srand(GetTickCount()); //  for(int i=0;i<rand()%(World::size*World::size*1000);i++) { //   ,     Land_MakeHill(World::data,rand()%(World::size),rand()%(World::size),World::size,-((rand()%20*1.0)+20)/100.0,rand()%4+7); } //  3   for(int i=0;i<3;i++) Land_Blur(World::data,World::size); 


After that I added some more small hills and flattened the map again.
Here's what happened:

Source: https://habr.com/ru/post/183986/


All Articles