2011-08-07 9 views
0

here,here,here、およびhereの情報に基づいて、2次元Perlinノイズ実装を作成しました。ただし、出力はthisのように見えます。ソフトウェアパーリンノイズの実装

public static double Perlin(double X, double XScale, double Y, double YScale, double Persistance, double Octaves) { 
    double total=0.0; 
    for(int i=0;i<Octaves;i++){ 
     int frq = (int) Math.Pow(2,i); 
     int amp = (int) Math.Pow(Persistance,i); 
     total += InterpolatedSmoothNoise((X/XScale) * frq, (Y/YScale) * frq) * amp; 
    } 
return total; 
} 

private static double InterpolatedSmoothNoise (double X, double Y) { 
int ix = (int) Math.Floor(X); 
double fx = X-ix; 
int iy = (int) Math.Floor(Y); 
double fy = Y-iy; 

double v1 = SmoothPerlin(ix,iy); //   -- 
double v2 = SmoothPerlin(ix+1,iy); //  +- 
double v3 = SmoothPerlin(ix,iy+1);//   -+ 
double v4 = SmoothPerlin(ix+1,iy+1);//  ++ 

double i1 = Interpolate(v1,v2,fx); 
double i2 = Interpolate(v3,v4,fx); 

    return Interpolate(i1,i2,fy); 
} 

private static double SmoothPerlin (int X, int Y) { 
    double sides=(Noise(X-1,Y,Z)+Noise(X+1,Y,Z)+Noise(X,Y-1,Z)+Noise(X,Y+1,Z)+Noise(X,Y,Z-1)+Noise(X,Y,Z+1))/12.0; 
    double center=Noise(X,Y,Z)/2.0; 
    return sides + center; 
} 

private static double Noise (int X, int Y) { 
uint m_z = (uint) (36969 * (X & 65535) + (X >> 16)); 
uint m_w = (uint) (18000 * (Y & 65535) + (Y >> 16)); 
uint ou = (m_z << 16) + m_w; 
return ((ou + 1.0) * 2.328306435454494e-10); 
} 

何か入力が間違っていると感謝します。

編集:私はこれを解決する方法を見つけました:これを修正するために負荷で生成された倍精度の配列を使用しました。しかし、良い乱数ジェネレータを実装する方法はありがたいです。

答えて

1

私はこの効果があなたのノイズ機能に起因すると考えます(他のコードはすべてOKです)。

機能

private static double Noise (int X, int Y) { 
    uint m_z = (uint) (36969 * (X & 65535) + (X >> 16)); 
    uint m_w = (uint) (18000 * (Y & 65535) + (Y >> 16)); 
    uint ou = (m_z << 16) + m_w; 
    return ((ou + 1.0) * 2.328306435454494e-10); 
} 

非常に騒々しいが、強くお入力XY変数と相関していません。あなたが入力した他の擬似ランダム関数を使ってみてください。

+0

ありがとう、私はそれを見ていきます。 –

+2

今私はほとんどの人がその実装でルックアップテーブルを使用する理由を知っています。 'new Random()。NextDouble()'は遅いです。 –

1

私はあなたのコードをCで再構築し、@Howardからの提案に従いました。このコードは私にとってうまくいきます。どの補間機能を使用したか分かりません。私は自分のコードで線形補間を使用しました。私は以下のノイズ関数を使用しました:

static double Noise2(int x, int y) { 
    int n = x + y * 57; 
    n = (n<<13)^n; 

    return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff)/1073741824.0); 
} 
+0

私はコサイン補間を使用しています。 –