2

我在这里尝试了快速而肮脏的代码翻译。

但是,我的版本输出的噪音与灰色 T 恤材料或石南花(如果你喜欢的话)相当:

#include <fstream>
#include "perlin.h"

double Perlin::cos_Interp(double a, double b, double x)
{
  ft = x * 3.1415927;
  f = (1 - cos(ft)) * .5;

  return a * (1 - f) + b * f;
}

double Perlin::noise_2D(double x, double y)
{
  /*
  int n = (int)x + (int)y * 57;
  n = (n << 13) ^ n;
  int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;

  return 1.0 - ((double)nn / 1073741824.0);
  */
  int n = (int)x + (int)y * 57;
  n = (n<<13) ^ n;
  return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);    
}

double Perlin::smooth_2D(double x, double y)
{
  corners = ( noise_2D(x - 1, y - 1) + noise_2D(x + 1, y - 1) + noise_2D(x - 1, y + 1) + noise_2D(x + 1, y + 1) ) / 16;
  sides   = ( noise_2D(x - 1, y) + noise_2D(x + 1, y) + noise_2D(x, y - 1) + noise_2D(x, y + 1) ) /  8;
  center  =  noise_2D(x, y) / 4;

  return corners + sides + center;
}

double Perlin::interp(double x, double y)
{
  int x_i = int(x);
  double x_left = x - x_i;

  int y_i = int(y);
  double y_left = y - y_i;

  double v1 = smooth_2D(x_i, y_i);
  double v2 = smooth_2D(x_i + 1, y_i);
  double v3 = smooth_2D(x_i, y_i + 1);
  double v4 = smooth_2D(x_i + 1, y_i + 1);

  double i1 = cos_Interp(v1, v2, x_left);
  double i2 = cos_Interp(v3, v4, x_left);

  return cos_Interp(i1, i2, y_left);
}

double Perlin::perlin_2D(double x, double y)
{
  double total = 0;
  double p = .25;
  int n = 1;

  for(int i = 0; i < n; ++i)
    {
      double freq =  pow(2, i);
      double amp = pow(p, i);

      total = total + interp(x * freq, y * freq) * amp;
    }

  return total;
}

int main()
{
  Perlin perl;
  ofstream ofs("./noise2D.ppm", ios_base::binary);

  ofs << "P6\n" << 512 << " " << 512 << "\n255\n";

  for(int i = 0; i < 512; ++i)
    {
      for(int j = 0; j < 512; ++j)
       {
         double n = perl.perlin_2D(i, j);

          n = floor((n + 1.0) / 2.0 * 255);

          unsigned char c = n;
          ofs << c << c << c;
       }
    }

  ofs.close();

  return 0;
}

除了添加 ppm 图像生成代码之外,我不相信我偏离上述站点的方向太远,但我再次承认没有完全掌握代码中发生的事情。

正如您将在评论部分看到的那样,我尝试了两种(相似的)生成噪声伪随机数的方法。我还尝试了将 perlin_2D 返回的数字缩放为 RGB 颜色值的不同方法。这两种编辑代码的方式刚刚产生了不同外观的 T 恤材料。所以,我不得不相信有更大的事情正在发生,我无法识别。

另外,我正在使用 g++ 和 c++11 标准进行编译。

编辑:这是一个例子:http: //imgur.com/Sh17QjK

4

2 回答 2

2

要将double[-1.0, 1.0] 范围内的 a 转换为 [0, 255] 范围内的整数:

n = floor((n + 1.0) / 2.0 * 255.99);

要将其作为二进制值写入 PPM 文件:

ofstream ofs("./noise2D.ppm", ios_base::binary);

...

    unsigned char c = n;
    ofs << c << c << c;
于 2014-07-19T19:25:57.183 回答
0

这是您的代码的直接副本吗?您将一个整数分配给应该是 Y 小数值的值 - 这是一个错字,如果您不修复它会抛出整个噪声算法:

 double Perlin::interp(double x, double y)
 {
     int x_i = int(x);
     double x_left = x - x_i;

     int y_i = int(y);
     double y_left = y = y_i;  //This Should have a minus, not an "=" like the line above

   .....

 }

我的猜测是,如果您使用正确的颜色计算成功生成位图,您会得到垂直条或沿着这些线的东西吗?

您还需要记住,Perlin 生成器通常会输出 -1 到 1 范围内的数字,您需要将结果值相乘:

值 * 127 + 128 = {R, G, B}

以获得良好的灰度图像。

于 2014-07-20T11:19:48.323 回答