Я создаю генератор высоты с использованием шума Perlin, как говорится в названии.Генерация высот с использованием Perlin Noise возвращает черное растровое изображение
я использовал псевдокод с этого сайта ->
и повернулся, чтобы C# код. до сих пор я выполнил все назначения типа переменной, и код дает результат. к сожалению, мой результат выглядит следующим образом:>
как вы можете видеть, правый и нижний края имеют небольшой градиент от черного до белого, но все остальное черное.
вот мой C# источник ->
private void button1_Click(object sender, EventArgs e) {
persistence = float.Parse(textBox4.Text);
NumberOfOctaves = Int32.Parse(textBox5.Text);
int width = Int32.Parse(textBox1.Text);
int height = Int32.Parse(textBox2.Text);
float zoom = float.Parse(textBox3.Text);
generate(width, height, zoom);
}
public float Noise(int x, int y) {
long n = x + (y * 57);
n = (long)Math.Pow((n << 13), n);
return (float)(1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff)/1073741824.0);
}
public float SmoothNoise(float x, float y) {
float corners = (Noise((int) (x-1), (int) (y-1)) + Noise((int) (x+1), (int) (y-1)) + Noise((int) (x-1), (int) (y+1)) + Noise((int) (x+1), (int) (y+1)))/16;
float sides = (Noise((int) (x-1), (int) y) + Noise((int) (x+1), (int) y) + Noise((int) x, (int) (y-1)) + Noise((int) x, (int) (y+1)))/8 ;
float center = Noise((int)x, (int)y)/4;
return corners + sides + center;
}
public float CosineInterpolate(float a, float b, float x) {
double ft = x * 3.1415927;
double f = (1 - Math.Cos(ft)) * 0.5;
return (float)((a * (1 - f)) + (b * f));
}
public float InterpolatedNoise(float x, float y) {
// MessageBox.Show(x.ToString());
int intX = (int)x;
float fractX = x - intX;
int intY = (int) y;
float fractY = y - intY;
float v1 = SmoothNoise(intX, intY);
float v2 = SmoothNoise(intX + 1, intY);
float v3 = SmoothNoise(intX, intY + 1);
float v4 = SmoothNoise(intX + 1, intY + 1);
float i1 = CosineInterpolate(v1 , v2 , fractX);
float i2 = CosineInterpolate(v3 , v4 , fractX);
// MessageBox.Show(intX + "\n" + intY + "\n" + fractX + "\n" + fractY + "\n" + v1 + "\n" + v2 + "\n" + v3 + "\n" + v4 + "\n" + i1 + "\n" + i2 + "\n" + CosineInterpolate(i1, i2, fractY));
return CosineInterpolate(i1 , i2 , fractY);
}
public float PerlinNoise2D(float x, float y) {
float total = 0;
float p = persistence;
int n = NumberOfOctaves;
for(int i = 0; i < n; i++) {
int frequency = (int)Math.Pow(2, i);
// MessageBox.Show(Math.Pow(2, i).ToString());
float amplitude = (int)Math.Pow(p, i);
total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
}
return total;
}
private void generate(int sizeX, int sizeY, float zoom) {
int zoomX = (int)(sizeX * zoom);
int zoomY = (int)(sizeY * zoom);
float max = int.MinValue;
float min = int.MaxValue;
float[,] nmap = new float[zoomX,zoomY];
Bitmap heightMap = new Bitmap(zoomX,zoomY);
for (int x=0; x<zoomX; x++) {
for (int y=0; y<zoomY; y++) {
// MessageBox.Show(PerlinNoise2D(x/zoom, y/zoom).ToString());
nmap[x,y] = PerlinNoise2D(x/zoom,y/zoom);
max = (max < nmap[x,y]) ? nmap[x,y] : max;
min = (min > nmap[x,y]) ? nmap[x,y] : min;
}
}
max = max-min;
for (int x=0; x<zoomX;x++) {
for (int y=0; y<zoomY;y++) {
int calc = (int) ((nmap[x,y] - min)/max);
heightMap.SetPixel(x,y,Color.FromArgb(calc,calc,calc));
}
}
pictureBox1.Image = heightMap;
}
также я мог загрузить визуальное решение студии в почтовый индекс, если кто-то хочет, чтобы.
До сих пор я узнал, что что-то не так с функцией Noise(), потому что оно возвращает -0,281 ... больше всего времени. он должен возвращать числа с плавающей запятой между -1.0 и 1.0. Я пробовал его с другими случайными функциями, но каждый раз выводит вывод.
Надеюсь, вы, ребята, можете мне помочь, и thx для аннуальных предложений.
Я предполагаю, что они имели в виду 0x7fffffff. Тем не менее, почему бы вам не попробовать использовать встроенный случайный класс C#? – redtuna
Я также пробовал его с помощью 0x7fffffff, но результат тот же. как я знаю, все сборки в случайных классах почти в каждом программируемом языке не на 100% случайны при значениях max & min ... Значения между min & max генерируют гораздо больше, чем значения, близкие к min & max ... – Ace
Туз, это любопытная вещь - вы смогли ее проверить? Разумеется, никакая детерминированная функция не будет на 100% случайной, но если ваша проблема в том, что ваша псевдослучайная функция нарушена, кажется разумным сначала попробовать встроенный, прежде чем писать свою собственную замену. – redtuna