【发布时间】:2020-08-19 05:37:48
【问题描述】:
我尝试制作一个程序,为地形生成生成梯度噪声。它应该打印 40 到 99 之间的数字数组,但它在这部分停止:
for(int k=16; k>1; k/=2)
for(int y=Y; y<Y+16; y+=k+1)
for(int x=X; x<X+16; x+=k+1)
{
tab[y+k/2][x]=rand()%(max(tab[y][x],tab[y+16][x])-min(tab[y][x],tab[y+16][x]))+min(tab[y][x],tab[y+16][x]);
tab[y][x+k/2]=rand()%(max(tab[y][x],tab[y][x+16])-min(tab[y][x],tab[y][x+16]))+min(tab[y][x],tab[y][x+16]);
tab[y+k/2][x+k/2]=rand()%(max(tab[y][x],tab[y+16][x+16])-min(tab[y][x],tab[y+16][x+16]))+min(tab[y][x],tab[y+16][x+16]);
}
当我删除循环的内容时,它不会停止。它编译得很好但返回 -1 (0xFFFFFFFF)
这是完整的代码:
#include<ctime>
#include<iostream>
using namespace std;
const short int Size=8;
short int tab[Size*16+1][Size*16+1];
void chunk(int X, int Y)
{
srand(time(NULL));
for(int k=16; k>1; k/=2)
for(int y=Y; y<Y+16; y+=k+1)
for(int x=X; x<X+16; x+=k+1)
{
tab[y+k/2][x]=rand()%(max(tab[y][x],tab[y+16][x])-min(tab[y][x],tab[y+16][x]))+min(tab[y][x],tab[y+16][x]);
tab[y][x+k/2]=rand()%(max(tab[y][x],tab[y][x+16])-min(tab[y][x],tab[y][x+16]))+min(tab[y][x],tab[y][x+16]);
tab[y+k/2][x+k/2]=rand()%(max(tab[y][x],tab[y+16][x+16])-min(tab[y][x],tab[y+16][x+16]))+min(tab[y][x],tab[y+16][x+16]);
}
}
int main()
{
srand(time(NULL));
for(int i=0; i<Size; i+=16)
for(int j=0; j<Size; j+=16)
tab[16*i][16*j]=rand()%(100-40)+40;
for(int x=0; x<Size*16+1; x+=16)
for(int y=0; y<Size*16+1; y+=16)
chunk(x,y);
return 0;
}
编辑: 它没有工作,因为
rand()%(max(tab[y][x],tab[y+16][x])-min(tab[y][x],tab[y+16][x]))
数组中的元素可以相等。 我在读取数组时也犯了一些愚蠢的错误,导致超出了它的大小。 现在它运行没有错误,但显示一些低于 40 的数字,这是不应该发生的。 这是修改后的代码:
#include<ctime>
#include<iostream>
using namespace std;
const short int Size=1;
short int tab[Size*16+1][Size*16+1];
void chunk(int X, int Y)
{
for(int k=16; k>1; k/=2)
for(int y=Y; y<Y+16; y+=k)
for(int x=X; x<X+16; x+=k)
{
if(Y!=Size*16)
if(tab[y][x]==tab[y+k][x])
tab[y+k/2][x]=tab[y][x];
else
tab[y+k/2][x]=rand()%(max(tab[y][x],tab[y+k][x])-min(tab[y][x],tab[y+k][x]))+min(tab[y][x],tab[y+k][x]);
if(X!=Size*16)
if(tab[y][x]==tab[y][x+k])
tab[y+k/2][x]=tab[y][x];
else
tab[y][x+k/2]=rand()%(max(tab[y][x],tab[y][x+k])-min(tab[y][x],tab[y][x+k]))+min(tab[y][x],tab[y][x+k]);
if(X!=Size*16||Y!=Size*16)
if(tab[y][x]==tab[y+k][x+k])
tab[y+k/2][x]=tab[y][x];
else
tab[y+k/2][x+k/2]=rand()%(max(tab[y][x],tab[y+k][x+k])-min(tab[y][x],tab[y+k][x+k]))+min(tab[y][x],tab[y+k][x+k]);
}
}
int main()
{
srand(time(NULL));
for(int i=0; i<=Size*16; i+=16)
for(int j=0; j<=Size*16; j+=16)
tab[j][i]=rand()%60+40;
for(int x=0; x<=Size*16; x+=16)
for(int y=0; y<=Size*16; y+=16)
chunk(x,y);
for(int a=0; a<Size*16; a++){
for(int b=0; b<Size*16; b++)
{
cout<<tab[b][a]<<' ';
if(tab[b][a]<10)
cout<<' ';
}
cout<<'\n';
}
return 0;
}
edit 2:算法将每 16 行和每列的两个选定值之间的伪随机值写入数组。然后它每 16 个单元格跳跃一次,在已经填充的单元格之间放置一个伪随机值,如下所示:
XOOOOOOO+OOOOOOF
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
+OOOOOOO+OOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOO
FOOOOOOOOOOOOOOF
X - 正在检查的单元格 F - 填充单元格 + - 要填充的单元格 0 - 空单元格 算法用“X”单元格和“F”单元格的值之间的伪随机值填充“+”单元格。当算法跳过所有“F”单元格时,它会再次跳转一半的时间,现有的“+”单元格变为“F”单元格。它一直持续到跳转长度等于 1,这意味着数组已满。
【问题讨论】:
-
相关问题:srand() — why call it only once?。因为
srand出现在您的函数中,所以当您在循环中调用您的函数时,函数的每次调用可能会生成完全相同的结果,因为它们可能会在time(NULL)返回的相同时间单位内执行。 -
您的
tab初始化已损坏。Size是 8,但您将循环变量增加 16,因此循环将始终只执行一次,i和j等于 0。我不知道为什么你然后将i和j乘以 16 来访问表元素,但看起来你忘记了你已经将迭代变量增加了 16。编辑:你可能将除以零从未正确初始化的tab读取。 -
感谢您提供重现问题的程序。当我运行您的代码时,我收到错误
Program received signal SIGFPE, Arithmetic exception.这是您的程序“停止”的意思吗?您是否尝试过使用调试器? gdb 显示第 13 行发生的错误:tab[y+k/2][x]=rand()%(max(tab[y][x],tab[y+16][x])-min(tab[y][x],tab[y+16][x]))+min(tab[y][x],tab[y+16][x]); -
似乎在第 13 行,它正在执行 rand()%(0),这会导致错误。
-
您能否编辑您的问题,添加一个关于算法应该做什么的简单解释(用英文而不是伪代码)?
标签: c++ noise-generator