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 画像生成コードを追加することを除けば、前述のサイトの指示から大きく逸脱したとは思いませんが、コードで何が起こっているのかを完全に把握していないことを認めます。

コメントのセクションでわかるように、ノイズの疑似乱数を生成する 2 つの (同様の) 方法を試しました。また、perlin_2D によって返された数値を RGB カラー値にスケーリングするさまざまな方法も試しました。コードを編集するこれら 2 つの方法により、異なる外観の 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 に答える