【问题标题】:C# XNA Perlin Noise, Array out of boundsC# XNA Perlin 噪声,数组越界
【发布时间】:2014-11-20 03:31:06
【问题描述】:

所以,在研究了这个:Wikipedia on Perlin Noise 之后,我尝试做一个生成 perlin 噪声纹理的类(输出为 Color[,],稍后将转换为纹理)。但是,一旦我让它运行,在所有运行中我都会得到一个越界异常。这是课程:

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;
    }

}
}

那么,我可以修改什么来解决这个问题?

提前致谢。

【问题讨论】:

  • 越界异常发生在哪里?
  • 它出现在代码中的注释...但是在DotGridGradient方法的返回行上。
  • 抱歉,我确实快速浏览了一下,没有发现它>_
  • 看起来你的循环在某个地方超出了限制。检查循环,因为你从 0 开始,所以结束值应该是 end-1 ......我想这是这样的问题。
  • 问题出在反面。由于某种原因,具有数组坐标的变量以负值开头...

标签: c# xna indexoutofboundsexception perlin-noise


【解决方案1】:

n1 你通过x1x。如果x 为零,则x0 为-1。 然后在方法DotGridGradient 中设置dxx0 - x,在本例中为-1 - 0。 y 也是如此。 这就是错误的原因。 如果你在生成它的 for 循环中从 1 开始,一切都很好。我对 Perlin Noises 一无所知,因此无法进一步帮助您。

【讨论】:

  • 是的,这就是发生的事情...问题是我开始理解它了,似乎柏林噪声值应该在 0 和 1 之间,而不是它的坐标...得重写实现,我猜……
猜你喜欢
  • 1970-01-01
  • 2014-02-15
  • 2014-05-21
  • 2020-06-06
  • 2011-09-20
  • 2021-06-30
  • 2013-07-23
  • 2020-06-22
  • 2011-03-19
相关资源
最近更新 更多