Advertisement
cheprogrammer

Perlin Noise

Feb 29th, 2016
880
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.44 KB | None | 0 0
  1. /// <summary>
  2. /// Класс для генерации Шума Перлина в двумерном пространстве
  3. /// </summary>
  4. public class PerlinNoiseGenerator
  5. {
  6.     public double GetNoise(int x, int y)
  7.     {
  8.         int n = x + y * 57;
  9.         n = (n << 13) ^ n;
  10.         return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
  11.     }
  12.  
  13.     private double SmoothNoise(double X, double Y)
  14.     {
  15.         int x = (int)X, y = (int)Y;
  16.  
  17.         double corners = (GetNoise(x - 1, y - 1) + GetNoise(x + 1, y - 1) + GetNoise(x - 1, y + 1) + GetNoise(x + 1, y + 1)) / 16;
  18.         double sides = (GetNoise(x - 1, y) + GetNoise(x + 1, y) + GetNoise(x, y - 1) + GetNoise(x, y + 1)) / 8;
  19.         double center = GetNoise(x, y) / 4;
  20.         return corners + sides + center;
  21.     }
  22.  
  23.  
  24.     private double CompileNoise(double x, double y)
  25.     {
  26.         int integer_X = (int)x;
  27.         double fractional_X = x - integer_X;
  28.  
  29.         int integer_Y = (int)y;
  30.         double fractional_Y = y - integer_Y;
  31.  
  32.         double v1 = SmoothNoise(integer_X, integer_Y);
  33.         double v2 = SmoothNoise(integer_X + 1, integer_Y);
  34.         double v3 = SmoothNoise(integer_X, integer_Y + 1);
  35.         double v4 = SmoothNoise(integer_X + 1, integer_Y + 1);
  36.  
  37.         double i1 = CosineInterpolation(v1, v2, fractional_X);
  38.         double i2 = CosineInterpolation(v3, v4, fractional_X);
  39.  
  40.         return CosineInterpolation(i1, i2, fractional_Y);
  41.     }
  42.  
  43.     public double GenerateNoise(double x, double y, double factor)
  44.     {
  45.         double total = 0;
  46.         // это число может иметь и другие значения хоть cosf(sqrtf(2))*3.14f
  47.         // главное чтобы было красиво и результат вас устраивал
  48.         double persistence = 0.5f;
  49.  
  50.         // экспериментируйте с этими значениями, попробуйте ставить
  51.         // например sqrtf(3.14f)*0.25f или что-то потяжелее для понимания J)
  52.         double frequency = 0.1f;
  53.         double amplitude = 0.5;//амплитуда, в прямой зависимости от значения настойчивости
  54.  
  55.         // рандомизация
  56.         x += (factor);
  57.         y += (factor);
  58.  
  59.         // NUM_OCTAVES - переменная, которая обозначает число октав,
  60.         // чем больше октав, тем лучше получается шум
  61.         int NUM_OCTAVES = 3;
  62.         for (int i = 0; i < NUM_OCTAVES; i++)
  63.         {
  64.             total += CompileNoise(x * frequency, y * frequency) * amplitude;
  65.             amplitude *= persistence;
  66.             frequency *= 2;
  67.         }
  68.  
  69.         total = Math.Abs(total);
  70.         return total;
  71.     }
  72.  
  73.     public double GenerateNoise(double x, double y, double factor, double persistence, double frequency, double amplitude)
  74.     {
  75.         double total = 0;
  76.  
  77.         // рандомизация
  78.         x += (factor);
  79.         y += (factor);
  80.  
  81.         // NUM_OCTAVES - переменная, которая обозначает число октав,
  82.         // чем больше октав, тем лучше получается шум
  83.         int NUM_OCTAVES = 3;
  84.         for (int i = 0; i < NUM_OCTAVES; i++)
  85.         {
  86.             total += CompileNoise(x * frequency, y * frequency) * amplitude;
  87.             amplitude *= persistence;
  88.             frequency *= 2;
  89.         }
  90.  
  91.         total = Math.Abs(total);
  92.         return total;
  93.     }
  94.  
  95.  
  96.     private double SimpleInterpolation(double a, double b, double x)
  97.     {
  98.         return a * (1 - x) + b * x;
  99.     }
  100.  
  101.     private double CosineInterpolation(double a, double b, double x)
  102.     {
  103.         double ft = x * 3.1415927;
  104.         double f = (1 - Math.Cos(ft)) * 0.5;
  105.         return a * (1 - f) + b * f;
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement