#include "StdAfx.h"
#include "PERLIN.h"



float Noise2D(int x, int y)
{
  int n = x + y * 57;
  n = (n<<13) ^ n;
  return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) /
      1073741824.0f);
}

float Noise2D(float X, float Y)
{
	int x = (int)X;
	int y = (int)Y;
  int n = x + y * 57;
  n = (n<<13) ^ n;
  return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) /
      1073741824.0f);
}

_inline float SmoothedNoise2D(float x, float y)
{
    float corners = ( Noise2D(x-1, y-1)+Noise2D(x+1, y-1)+
         Noise2D(x-1, y+1)+Noise2D(x+1, y+1) ) / 16;
    float sides   = ( Noise2D(x-1, y)  +Noise2D(x+1, y)  +
         Noise2D(x, y-1)  +Noise2D(x, y+1) ) /  8;
    float center  =  Noise2D(x, y) / 4;
    return corners + sides + center;
  }

float  Cosine_Interpolate(float a,float b,float x)
{
  float ft = x * 3.1415927f;
  float f = (1 - cosf(ft)) * 0.5f;
  return  (a*(1-f) + b*f);  
}

float CompileNoise(float x, float y) 
{
      float int_X    = int(x);//целая часть х
      float fractional_X = x - int_X;//дробь от х
//аналогично у
      float int_Y    = int(y);
      float fractional_Y = y - int_Y;
  //получаем 4 сглаженных значения
     float v1 = SmoothedNoise2D(int_X,     int_Y);
     float v2 = SmoothedNoise2D(int_X + 1, int_Y);
     float v3 = SmoothedNoise2D(int_X,     int_Y + 1);
     float v4 = SmoothedNoise2D(int_X + 1, int_Y + 1);
  //интерполируем значения 1 и 2 пары и производим интерполяцию между ними
      float i1 = Cosine_Interpolate(v1 , v2 , fractional_X);
      float i2 = Cosine_Interpolate(v3 , v4 , fractional_X);
  //я использовал косинусною интерполяцию ИМХО лучше 
  //по параметрам быстрота-//качество
      return Cosine_Interpolate(i1 , i2 , fractional_Y);
}