2014-09-25 4 views
1

Итак, изучив это: Wikipedia on Perlin Noise, я попытался создать класс, который генерирует текстуру шума perlin (выводится как Color [,], которая позже будет преобразована в текстуру). Однако, как только я запустил его, во всех прогонах я получаю исключение за пределы. Вот этот класс:C# XNA Perlin Noise, Array за пределами

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

Где происходит исключение из-за пределов? –

+1

Прокомментирован в коде, где это происходит ... Но это на обратной линии метода DotGridGradient. –

+0

Извините, я быстро просмотрел его, не заметил его> _ < –

ответ

0

В n1 вы проходите x1 и x. если x равно нулю, то x0 равно -1. Затем вы используете метод DotGridGradient, который вы установили dx в x0 - x, который в этом случае равен -1 - 0. То же самое касается y. Вот что вызывает ошибка. Если вы начинаете с 1 в цикле for, генерируя его, все в порядке. Я ничего не знаю о Perlin Noises, поэтому я не могу вам помочь.

+0

Да, вот что случилось ... Дело в том, что я начинаю понимать это, хотя кажется, что значения шума perlin должны находиться в диапазоне от 0 до 1, а не с его координатами ... Должен переписать реализацию, я думаю ... –