Advertisement
cybercritic

diamond_square_algorithm

Nov 8th, 2018
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.15 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class MidPointHeight
  6. {
  7.     public int Size { get; set; }
  8.     public float FallOff { get; set; }
  9.     public bool Wrap { get; set; }
  10.  
  11.     public int cSize { get; private set; }
  12.     public float cDeviance { get; private set; }
  13.  
  14.     public static float cRange { get; set; }
  15.  
  16.     private Random rand;
  17.    
  18.     public float[,] heights { get; private set; }
  19.  
  20.     public MidPointHeight(int Seed, bool Wrap, float Range)
  21.     {
  22.         this.FallOff = 0.495f;
  23.         this.rand = new Random(Seed != -1 ? Seed : (int)DateTime.UtcNow.Ticks);
  24.         this.Wrap = Wrap;
  25.         this.cSize = 2;
  26.         this.cDeviance = 1.0f;
  27.         cRange = Range;
  28.  
  29.         this.heights = new float[cSize, cSize];
  30.  
  31.         //init minium
  32.         if (this.Wrap)
  33.         {
  34.             this.heights[0, 0] = this.rand.GetHeight();
  35.             this.heights[0, 1] = this.heights[0, 0];
  36.             this.heights[1, 0] = this.heights[0, 0];
  37.             this.heights[1, 1] = this.heights[0, 0];
  38.         }
  39.         else
  40.         {
  41.             this.heights[0, 0] = this.rand.GetHeight();
  42.             this.heights[0, 1] = this.rand.GetHeight();
  43.             this.heights[1, 0] = this.rand.GetHeight();
  44.             this.heights[1, 1] = this.rand.GetHeight();
  45.         }
  46.     }
  47.  
  48.     public void MakeStep()
  49.     {
  50.         this.heights = this.DiamondStep(this.heights);
  51.         this.SquareStep(this.heights);
  52.     }
  53.  
  54.     private float[,] DiamondStep(float[,] data)
  55.     {
  56.         this.cDeviance *= this.FallOff;
  57.  
  58.         int oldSize = cSize;
  59.         cSize = cSize * 2 - 1;
  60.         float[,] result = new float[cSize, cSize];
  61.  
  62.         for (int x = 0, nx = 1; x < oldSize - 1; x++, nx += 2)
  63.             for (int y = 0, ny = 1; y < oldSize - 1; y++, ny += 2)
  64.             {
  65.                 float hlt = data[x, y];
  66.                 float hrt = data[x + 1, y];
  67.                 float hlb = data[x, y + 1];
  68.                 float hrb = data[x + 1, y + 1];
  69.  
  70.                 float add = 0f;
  71.                 if (y % 2 == 0)
  72.                     if (x % 2 == 0) { add += hrb + hlt; } else { add += hlb + hrt; }
  73.                 else
  74.                     if (x % 2 == 0) { add += hrt + hlb; } else { add += hlt + hrb; }
  75.  
  76.                 float mid = (hlt + hrt + hlb + hrb + add) / 6.0f;
  77.                 float offset = (this.rand.GetHeight() * this.cDeviance);
  78.  
  79.                 result[nx, ny] = (mid + offset);
  80.  
  81.                 //set existing heights
  82.                 result[nx - 1, ny - 1] = hlt;
  83.                 result[nx + 1, ny - 1] = hrt;
  84.                 result[nx - 1, ny + 1] = hlb;
  85.                 result[nx + 1, ny + 1] = hrb;
  86.             }
  87.  
  88.         return result;
  89.     }
  90.  
  91.     private void SquareStep(float[,] data)
  92.     {
  93.         for (int y = 0; y < cSize; y++)
  94.             for (int x = y % 2 == 0 ? 1 : 0; x < cSize; x += 2)
  95.             {
  96.                 if (data[x, y] != 0)
  97.                     continue;
  98.  
  99.                 float l = (x - 1 < 0) ? float.NaN : data[x - 1, y];
  100.                 float r = (x + 1 >= cSize) ? float.NaN : data[x + 1, y];
  101.                 float t = (y - 1 < 0) ? float.NaN : data[x, y - 1];
  102.                 float b = (y + 1 >= cSize) ? float.NaN : data[x, y + 1];
  103.  
  104.                 if (float.IsNaN(l)) { if (this.Wrap) { data[x, y] = this.GetMissingPoint(cSize - 1, y, data, (r + t + b)); continue; } else l = r; }
  105.                 if (float.IsNaN(r)) { if (this.Wrap) { data[x, y] = this.GetMissingPoint(0, y, data, (l + t + b)); continue; } else r = l; }
  106.                 if (float.IsNaN(t)) { if (this.Wrap) { data[x, y] = this.GetMissingPoint(x, cSize - 1, data, (l + r + b)); continue; } else t = b; }
  107.                 if (float.IsNaN(b)) { if (this.Wrap) { data[x, y] = this.GetMissingPoint(x, 0, data, (l + r + t)); continue; } else b = t; }
  108.  
  109.                 float mid = x % 2 == 0 ? (l + r + t * 2f + b * 2f) / 6.0f : (l * 2f + r * 2f + t + b) / 6.0f;
  110.                 float offset = this.rand.GetHeight() * this.cDeviance;
  111.  
  112.                 data[x, y] = (mid + offset);
  113.             }
  114.     }
  115.  
  116.     private float GetMissingPoint(int x, int y, float[,] data, float height)
  117.     {
  118.         float l = x - 1 < 0 ? float.NaN : data[x - 1, y];
  119.         float r = x + 1 >= cSize ? float.NaN : data[x + 1, y];
  120.         float t = y - 1 < 0 ? float.NaN : data[x, y - 1];
  121.         float b = y + 1 >= cSize ? float.NaN : data[x, y + 1];
  122.  
  123.         if (float.IsNaN(l)) l = 0;
  124.         if (float.IsNaN(r)) r = 0;
  125.         if (float.IsNaN(b)) b = 0;
  126.         if (float.IsNaN(t)) t = 0;
  127.  
  128.         float mid = (l + r + t + b + height) / 6.0f;
  129.         float res = mid + (this.rand.GetHeight() * this.cDeviance);
  130.         data[x, y] = res;
  131.  
  132.         return res;
  133.     }
  134.  
  135.     public static float Clamp(float value, float min, float max)
  136.     {
  137.         return value > max ? max : value < min ? min : value;
  138.     }
  139. }
  140.  
  141. public static class MyExtensions
  142. {
  143.     public static float GetHeight(this Random rnd)
  144.     {
  145.         return (float)(rnd.NextDouble() * MidPointHeight.cRange - (MidPointHeight.cRange / 2.0f));
  146.     }
  147. }
  148.  
  149. public class MeshData
  150. {
  151.     public int Size { get; set; }
  152.     public float[,] Heights { get; set; }
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement