我正在尝试在游戏中实现程序生成。我想真正掌握并理解所有算法,而不是简单地复制/粘贴现有代码。为了做到这一点,我试图自己实现1D中点位移。我已经使用信息here来编写和指导我的代码。下面是我完成的代码,它不会抛出错误,但结果看起来不正确。
srand(time(NULL));
const int lineLength = 65;
float range = 1.0;
float displacedLine[lineLength];
for (int i = 0; i < lineLength; i++)
{
displacedLine[i] = 0.0;
}
for (int p = 0; p < 100; p++)
{
int segments = 1;
for (int i = 0; i < (lineLength / pow(2, 2)); i++)
{
int segs = segments;
for (int j = 0; j < segs; j++)
{
int x = floor(lineLength / segs);
int start = (j * x) + 1;
int end = start + x;
if (i == 0)
{
end--;
}
float lo = -range;
float hi = +range;
float change = lo + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (hi - lo)));
int center = ((end - start) / 2) + start;
displacedLine[center - 1] += change;
segments++;
}
range /= 2;
}
}
我究竟在哪里犯错,我怎么纠正错误?
我得到的结果如下:
但我期待这样的结果:
答案 0 :(得分:1)
答案非常简单,顺便说一下,我给你留下了深刻的印象,你设法调试代码中所有潜在的错误。以下行错误:
displacedLine[center - 1] += change;
您正确计算了中心索引并更改了金额,但您错过了该更改应该应用于高度方面的中点。那就是:
displacedLine[center - 1] = (displacedLine[start] + displacedLine[end]) / 2;
displacedLine[center - 1] += change;
我相信你明白了。
答案 1 :(得分:0)
问题似乎是你只改变每个线段的中点,而不是改变线段的其余部分与它从每个端点到中点的距离成比例。以下代码似乎为您提供了更多您喜欢的内容:
#include <iostream>
#include <cstdlib>
#include <math.h>
#include <algorithm>
using namespace std;
void displaceMidPt (float dline[], int len, float disp) {
int midPt = len/2;
float fmidPt = float(midPt);
for (int i = 1; i <= midPt; i++) {
float ptDisp = disp * float(i)/fmidPt;
dline[i] += ptDisp;
dline[len-i] += ptDisp;
}
}
void displace (float displacedLine[], int lineLength, float range) {
for (int p = 0; p < 100; p++) {
int segs = pow(p, 2);
for (int j = 0; j < segs; j++) {
float lo = -range;
float hi = +range;
float change = lo + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (hi - lo)));
int start = int(float(j)/float(segs)*float(lineLength));
int end = int(float(j+1)/float(segs)*float(lineLength));
displaceMidPt (displacedLine+start,end-start,change);
}
range /= 2;
}
}
void plot1D (float x[], int len, int ht = 10) {
float minX = *min_element(x,x+len);
float maxX = *max_element(x,x+len);
int xi[len];
for (int i = 0; i < len; i++) {
xi[i] = int(ht*(x[i] - minX)/(maxX - minX) + 0.5);
}
char s[len+1];
s[len] = '\0';
for (int j = ht; j >= 0; j--) {
for (int i = 0; i < len; i++) {
if (xi[i] == j) {
s[i] = '*';
} else {
s[i] = ' ';
}
}
cout << s << endl;
}
}
int main () {
srand(time(NULL));
const int lineLength = 65;
float range = 1.0;
float displacedLine[lineLength];
for (int i = 0; i < lineLength; i++) {
displacedLine[i] = 0.0;
}
displace (displacedLine,lineLength,range);
plot1D (displacedLine,lineLength);
return 0;
}
以这种方式运行时,会产生以下结果:
$ c++ -lm displace.cpp
$ ./a
*
* *
* ***
* * * *
* ** **** * **
* *** **** * * * ** *
* * ** ** *** * * * *
** ** *
* * * ***
** ***
*