3

我正在尝试在我的游戏中实现程序生成。我想真正掌握和理解所有必要的算法,而不是简单地复制/粘贴现有​​代码。为了做到这一点,我尝试自己实现一维中点位移。我使用这里的信息来编写和指导我的代码。下面是我完成的代码,它不会引发错误,但结果似乎不正确。

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

我到底在哪里犯了错误,我该如何纠正它们?

我得到这样的结果:

我的结果

但我期待这样的结果:

预期成绩

4

2 回答 2

1

答案非常简单,顺便说一句,我印象深刻的是,您设法调试了代码中所有潜在的错误。以下行是错误的:

displacedLine[center - 1] += change;

您正确计算了中心索引和更改量,但您错过了应该将更改应用于height 的中点。那是:

displacedLine[center - 1] = (displacedLine[start] + displacedLine[end]) / 2;
displacedLine[center - 1] += change;

我相信你明白了。

于 2014-01-03T05:32:09.880 回答
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
                                  *
                              *       *
                                 * ***
                             * *       *             *
                         * **            ****       * **
      * ***  ****  *   *                *    **         *
     * *   **    ** ***   *     *                * *
   **                                          **        *
  *                     *                         *       ***
**                                                            ***
                                                             *
于 2014-01-03T05:16:58.577 回答