diamondsquare.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. Copyright (C) 2015 Marien Raat
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <random>
  15. #include <iostream>
  16. #include <functional>
  17. // The map array is a one dimensional array used to describe a two
  18. // dimensional array. The array is layed out with the rows next to
  19. // each other, so (x, y) kan be accesed on the index x + y * width.
  20. // To ease the use of this array, the simple macro TO_ARRAY_INDEX
  21. // is provided.
  22. #define TO_ARRAY_INDEX(x, y, width) (x + y * width)
  23. enum DiamondSquareMapType {
  24. MAPTYPE_LAND = 0,
  25. MAPTYPE_ISLAND,
  26. MAPTYPE_ARCHIPELAGO
  27. };
  28. struct DiamondSquareMapSettings{
  29. int size; // Size of the square, should be a power of 2 plus 1
  30. double h; // The displacement will be decreased by 2 ^ (- h) each pass
  31. // A high h-value will result in a smooth map and a low h-value
  32. // will result in a rough maps
  33. DiamondSquareMapType mapType;
  34. bool overwriteOldMap; // If false, new space will be allocated in the
  35. // heap for the new map.
  36. // The user of the class is responsible for cleaning
  37. // up all maps and repeatedly running with this as
  38. // false will leak memory.
  39. double (*modifierFunction)(int, double);
  40. };
  41. struct PassSettings {
  42. double *map; // Map to run the pass on
  43. double displacementModifier; // Displacement from drand() is multiplied
  44. // by this value. Given by 2 ^ (- (h * pass))
  45. int passSize; // Length of the sides of the square
  46. int mapSize; // Size of each side of the map
  47. };
  48. class HeightmapGenerator {
  49. public:
  50. HeightmapGenerator(std::mt19937 *mt);
  51. ~HeightmapGenerator();
  52. void createNewMap(DiamondSquareMapSettings settings);
  53. void pass(); // Apply the next pass to the map if it is made and
  54. // it is not done
  55. void finishMap(); // Calls pass() until isMapDone
  56. void normalizeMap();
  57. bool isMapDone();
  58. PassSettings currentPassSettings;
  59. double *map;
  60. private:
  61. DiamondSquareMapSettings currentMapSettings;
  62. bool mapInitialized, firstMap;
  63. std::mt19937 *mt;
  64. std::normal_distribution<double> *stdDist;
  65. void passDiamondSquare(PassSettings *settings);
  66. void diamond(int x, int y, PassSettings *settings);
  67. void square(int x, int y, PassSettings *settings);
  68. bool isValid(int x, int y, int size);
  69. double drand(); // Returns a random double between -1.0 and 1.0
  70. // using the given mt and the stdDist
  71. void fillSidesWith(double *map, double cornerValue, int size);
  72. };
  73. // Simple functions to use as modifier functions
  74. double logaritmicDisplacementModifier(int pass, double h);
  75. double customDisplacementModifier(int pass, double h);