2014-09-25 109 views
1

因此,在研究了這個問題後:Wikipedia on Perlin Noise,我試圖做一個生成perlin噪聲紋理的類(作爲一個Color [,]輸出,稍後將被轉換爲紋理)。但是,一旦我運行,在所有運行中,我都會遇到越界異常。這裏的課程:C#XNA Perlin噪聲,數組越界

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 


namespace Noise 
{ 
class PerlinNoise : Noise 
{ 
    private float[,,] gradient; 
    private float[,] noise; 
    private bool generated; 
    private int width; 
    private int height; 

    /// <summary> 
    /// Class constructor. 
    /// </summary> 
    /// <param name="x">Width of the perlin noise</param> 
    /// <param name="y">Height of the perlin noise</param> 
    public PerlinNoise(int width, int height) 
    { 
     gradient = new float[width,height,2]; 

     Random r = new Random(); 

     for (int i = 0; i < width; i++) 
     { 
      for (int o = 0; o < height; o++) 
      { 
       for (int p = 0; p < 2; p++) 
       { 
        gradient[i, o, p] = ((float)r.NextDouble() * 2f) -1; 
       } 
      } 
     } 

     this.width = width; 
     this.height = height; 
     noise = new float[width, height]; 
     generated = false; 


    } 



    float Lerp(float a0, float a1, float w) 
    { 
     return (1.0f - w) * a0 + w * a1; 
    } 

    float DotGridGradient(int ix, int iy, float x, float y) 
    { 
     float dx = x - (float)ix; 
     float dy = y - (float)iy; 


     return (dx * gradient[iy, ix, 0]) + (dy * gradient[iy, ix, 1]); //It blows up here, usually with either iy or ix = -1 
    } 

    public float GenerateValue(float x, float y) 
    { 

     int x0 = x > 0.0f ? (int)x : (int)x - 1; 
     int x1 = x0 + 1; 
     int y0 = y > 0.0f ? (int)y : (int)y - 1; 
     int y1 = y0 + 1; 

     float sx = x - (float)x0; 
     float sy = y - (float)y0; 

     float n0, n1, ix0, ix1, value; 
     n0 = DotGridGradient(x0, y0, x, y); 
     n1 = DotGridGradient(x1, y0, x, y); 
     ix0 = Lerp(n0, n1, sx); 
     n0 = DotGridGradient(x0, y1, x, y); 
     n1 = DotGridGradient(x1, y1, x, y); 
     ix1 = Lerp(n0, n1, sx); 
     value = Lerp(ix0, ix1, sy); 

     return value; 

    } 

    public Color GenerateColor(int x, int y) 
    { 
     if (!generated) GenerateNoise(); 

     Color c = new Color(); 
     c.R = c.G = c.B = (byte)(256 * noise[x,y]); 
     return c; 
    } 

    public Color[,] GenerateTexture() 
    { 
     if (!generated) GenerateNoise(); 

     Color[,] color = new Color[width,height]; 

     for (int x = 0; x < width; x++) 
     { 

      for (int y = 0; y < height; y++) 
      { 
       color[x, y] = GenerateColor(x, y); 
      } 


     } 

     return color; 
    } 

    public void GenerateNoise() 
    { 
     for (int x =0; x < width; x++) 
      for (int y = 0; y < height; y++) 
       noise[x, y] = GenerateValue(x, y); 


     generated = true; 
    } 

} 
} 

那麼,我可以修改,以解決這個問題?

在此先感謝。

+0

哪裏出現越界異常? – 2014-09-25 11:32:19

+1

它在代碼中發生了註釋...但它在DotGridGradient方法的返回行中。 – 2014-09-25 11:33:41

+0

對不起,我確實有一個快速瀏覽它,沒有發現它> _ < – 2014-09-25 12:12:00

回答

0

n1你通過x1x。如果x爲零,則x0爲-1。 然後你在方法DotGridGradient中設置dxx0 - x,在這種情況下爲-1-0。 同樣適用於y。 這就是錯誤的原因。 如果你在for循環中從1開始,那麼一切都很好。我對佩林噪聲一無所知,所以我無法進一步幫助你。

+0

是的,這就是發生了什麼......事情是,我開始瞭解它,但似乎perlin噪聲值應該介於0和1,而不是它的座標...要重寫實現,我猜... – 2014-09-26 11:46:34