Как реализовать смещение средней точки

Я пытаюсь реализовать процедурную генерацию в моей игре. Я хочу по-настоящему понять и понять все необходимые алгоритмы, а не просто копировать / вставлять существующий код. Чтобы сделать это, я попытался реализовать 1-мерное смещение средней точки самостоятельно. Я использовал информацию Вот написать и направить мой код. Ниже мой законченный код, он не выдает ошибку, но результаты не отображаются правильно.

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

Где именно я допустил ошибки и как их исправить?

Я получаю результаты, как это:

Мои результаты

Но я ожидал таких результатов:

Ожидаемые результаты

3

Решение

Ответ очень прост, и, кстати, я впечатлен, что вам удалось отладить все потенциальные ошибки в вашем коде. Следующая строка неверна:

displacedLine[center - 1] += change;

Вы правильно вычислили центральный индекс и изменили сумму, но упустили, что изменение должно быть применено к средняя точка по высоте. То есть:

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

Я уверен, что вы поняли идею.

1

Другие решения

Кажется, проблема в том, что вы изменяете только среднюю точку каждого отрезка, а не изменяете остальную часть отрезка пропорционально его расстоянию от каждого конца до середины. Следующий код, кажется, дает вам нечто похожее на то, что вы ищете:

#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
*
*       *
* ***
* *       *             *
* **            ****       * **
* ***  ****  *   *                *    **         *
* *   **    ** ***   *     *                * *
**                                          **        *
*                     *                         *       ***
**                                                            ***
*
0

По вопросам рекламы [email protected]