Advertisement
SebastianLague

Blob map

Oct 16th, 2017
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.41 KB | None | 0 0
  1. public static float[,] GenerateBlobMap(int sizeX, int sizeY, float fillPercent, int seed, int blurSize, int blurIterations) {
  2.     float[,] map = new float[sizeX,sizeY];
  3.  
  4.     float halfWidth = (sizeX - 1) / 2f;
  5.     float halfHeight = (sizeY - 1) / 2f;
  6.  
  7.     System.Random prng = new System.Random (seed);
  8.     float totalArea = sizeX * sizeY;
  9.     float coveredArea = 0;
  10.     int blurExtents = blurSize * blurIterations + 1;
  11.  
  12.     const int minRadius = 5;
  13.     int maxBlobRadius = (int)Mathf.Clamp (Mathf.Min (halfWidth, halfHeight) - blurExtents, minRadius, float.MaxValue);
  14.     fillPercent = Mathf.Clamp01 (fillPercent);
  15.  
  16.     const int maxIterations = 200;
  17.  
  18.     int iterationCount = 0;
  19.     while (coveredArea / totalArea < fillPercent*.95f && iterationCount < maxIterations) {
  20.         iterationCount++;
  21.  
  22.         int posX = prng.Next (blurExtents + minRadius, sizeX - (blurExtents + minRadius));
  23.         int posY = prng.Next (blurExtents + minRadius, sizeY - (blurExtents + minRadius));
  24.         int dstToClosestEdge = (int)Mathf.Min (halfWidth - Mathf.Abs (halfWidth - posX), halfHeight - Mathf.Abs (halfHeight - posY));
  25.         int maxRadius = dstToClosestEdge - blurExtents;
  26.  
  27.  
  28.         float targetFillArea = totalArea - coveredArea;
  29.         float targetRadius = Mathf.Sqrt(targetFillArea / 3.14f);
  30.         int blobRadius = Mathf.Min(Mathf.RoundToInt(targetRadius),maxRadius);
  31.  
  32.         for (int i = 0; i < blobRadius*2; i++) {
  33.             for (int j = 0; j < blobRadius*2; j++) {
  34.                 float x =blobRadius - i;
  35.                 float y =blobRadius - j;
  36.                 int ix = posX - blobRadius + i;
  37.                 int iy = posY - blobRadius + j;
  38.  
  39.                 if (Mathf.Pow (x * x + y * y, .5f) < blobRadius) {
  40.                     map [ix, iy] = 1;
  41.                 }
  42.             }
  43.         }
  44.         coveredArea += blobRadius * blobRadius * 3.14f;
  45.  
  46.     }
  47.  
  48.     for (int i = 0; i < blurIterations; i++) {
  49.         Blur (ref map, blurSize);
  50.     }
  51.  
  52.     for (int i = 0; i < sizeX; i++) {
  53.         for (int j = 0; j < sizeY; j++) {
  54.             map [i, j] = 1 - map [i,j];
  55.         }
  56.     }
  57.  
  58.     return map;
  59.  
  60. }
  61.  
  62. static void Blur (ref float[,] image, int blurSize) {
  63.     int width = image.GetLength (0);
  64.     int height = image.GetLength (1);
  65.  
  66.     int kernelSize = blurSize * 2 + 1;
  67.     int kernelExtents = blurSize;
  68.  
  69.     float[,] horizontalBlurPass = new float[width,height];
  70.     float[,] verticalBlurPass = new float[width,height];
  71.  
  72.     for (int y = 0; y < height; y++) {
  73.         for (int x = -kernelExtents; x <= kernelExtents; x++) {
  74.             int sampleX = Mathf.Clamp (x, 0, kernelExtents);
  75.             horizontalBlurPass [0, y] += image [sampleX, y];
  76.         }
  77.  
  78.         for (int x = 1; x < width; x++) {
  79.             int removeIndex = Mathf.Clamp(x - kernelExtents - 1, 0, width);
  80.             int addIndex = Mathf.Clamp(x + kernelExtents, 0, width-1);
  81.  
  82.             horizontalBlurPass [x, y] = horizontalBlurPass [x - 1, y] - image [removeIndex, y] + image [addIndex, y];
  83.         }
  84.     }
  85.  
  86.     for (int x = 0; x < width; x++) {
  87.         for (int y = -kernelExtents; y <= kernelExtents; y++) {
  88.             int sampleY = Mathf.Clamp (y, 0, kernelExtents);
  89.             verticalBlurPass [x, 0] += horizontalBlurPass [x, sampleY];
  90.         }
  91.  
  92.         float blurredValue = (verticalBlurPass [x, 0] / (kernelSize * kernelSize));
  93.         image [x, 0] = blurredValue;
  94.  
  95.         for (int y = 1; y < height; y++) {
  96.             int removeIndex = Mathf.Clamp(y - kernelExtents - 1, 0, height);
  97.             int addIndex = Mathf.Clamp(y + kernelExtents, 0, height-1);
  98.  
  99.             verticalBlurPass [x, y] = verticalBlurPass [x, y-1] - horizontalBlurPass [x,removeIndex] + horizontalBlurPass [x, addIndex];
  100.             blurredValue = ((float)verticalBlurPass [x, y] / (kernelSize * kernelSize));
  101.             image [x, y] = blurredValue;
  102.         }
  103.     }
  104.  
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement