keldon85

Fractal terrain generation

Aug 3rd, 2012
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.03 KB | None | 0 0
  1. /**
  2.  * The Terrain Generator class produces random generated terrains.
  3.  * @author avasopht.blogspot.com
  4.  *
  5.  */
  6. public class TerrainGenerator {
  7.   /**
  8.    * Returns a square height map in a series of iterations. Each iteration doubles the size
  9.    * of the map until the map meets the minimum size requirements.
  10.    * @param roughness between 0.0 and 1.0, with 0.0 being rough and 1.0 being smooth
  11.    */
  12.   public static HeightMap GenerateHeightMap(int minimumWidth, int minimumHeight, float roughness){
  13.     float displacementMagnitude = 1.0f;
  14.     // Create map with a random height
  15.     HeightMap map = new HeightMap(1,1);
  16.     map.setValue(0,0,0);
  17.    
  18.     // For each iteration
  19.     while(map.getWidth() < minimumWidth && map.getHeight() < minimumHeight) {
  20.       // Create a new map twice the size of the current map
  21.       // Copy old map height data to new map
  22.       map = map.GetDoubleSized();
  23.      
  24.       // (Diamond step): for each square
  25.       for(int x = 0; x < map.getWidth(); x += 2) {
  26.         for(int y = 0; y < map.getHeight(); y += 2) {
  27.           // Calculate average value of square
  28.           float average = GetSquareAverage(map,x,y);
  29.           // Produce midpoint displacement value
  30.           float midpoint = average + CreateRandomValue(displacementMagnitude);
  31.           map.setValue(x + 1, y + 1, midpoint);
  32.         }
  33.       }
  34.      
  35.       // (Square step): for each diamond
  36.       for(int x = 0; x < map.getWidth(); x += 2) {
  37.         for(int y = 0; y < map.getHeight(); y += 2) {
  38.           // Calculate average value of corners
  39.           // Produce midpoint displacement value
  40.           CalculateDiamond(map, x+1, y, displacementMagnitude);
  41.           CalculateDiamond(map, x, y+1, displacementMagnitude);
  42.         }
  43.       }
  44.      
  45.       // Update displacement magnitude
  46.       displacementMagnitude = displacementMagnitude * (1.0f -  (roughness * 0.5f));
  47.     }
  48.    
  49.     // Return height map
  50.     return map.GetNormalized();
  51.   }
  52.  
  53.   /**
  54.    * Calculates new value inside of a diamond.
  55.    */
  56.   private static void CalculateDiamond(HeightMap map, int x, int y, float magnitude) {
  57.     float sum = 0;
  58.     // Calculate average value of corners
  59.     sum += map.getValue(x-1,y);
  60.     sum += map.getValue(x+1,y);
  61.     sum += map.getValue(x,y+1);
  62.     sum += map.getValue(x,y-1);
  63.     float average = sum / 4.0f;
  64.    
  65.     // Produce midpoint displacement value
  66.     float midpoint = average + CreateRandomValue(magnitude);
  67.     map.setValue(x,y,midpoint);
  68.   }
  69.  
  70.   /**
  71.    * Calculates the average value of the corners in a 3x3 square.
  72.    */
  73.   private static float GetSquareAverage(HeightMap map, int x, int y) {
  74.     float sum = 0;
  75.     for(int readX = 0; readX < 2; readX++) {
  76.       for(int readY = 0; readY < 2; readY++) {
  77.         sum += map.getValue(x + readX * 2, y + readY * 2);
  78.       }
  79.     }
  80.     return sum / 4.0f;
  81.   }
  82.  
  83.   /**
  84.    * Returns a random value between -magnitude and magnitude.
  85.    */
  86.   private static float CreateRandomValue(float magnitude) {
  87.     return (float)(magnitude * ((2.0f * Math.random()) - 1.0f));
  88.   }
  89. }
Advertisement
Add Comment
Please, Sign In to add comment