Diamond Square Terrain Generation для больших площадей

Я пытаюсь реализовать алгоритм генерации рельефа алмазного квадрата в OpenGL.

Пока у меня есть 2D-плоскость (фактически 3D, но все координаты Z установлены на 0), состоящая из 1024 различных квадратов. Координаты организованы в 2-мерные массивы

  • Массив для x-координат: xMap [1024] [1024]
  • Массив для y-координат: yMap [1024] [1024]
  • Массив для z-координат: zMap [1024] [1024] (все = 0 в начале; ошибочно предполагая, что z является «вертикальной» осью в нашем случае)

У нас есть, например:

Point1 (xMap[1][1], yMap[1][1], zMap[1][1]);

Я использую следующий код для создания ландшафта. Проблема, с которой я столкнулся, заключается в том, что, хотя она работает, как и ожидалось, на картах размером 4 х 4, она не работает ни на чем большем. При применении к карте 6 X 6 он будет генерировать ландшафт соответственно для 4 X 4, но оставит добавленные 2 квадрата нетронутыми.

Вот код, который я использую для создания ландшафта:

   void generateLandscapeRec(int xMin, int xMax, int yMin, int yMax, float disp) {

float nDisp = (float)(disp * (float)pow(2, -(double)roughnes)); // New displacement

int xMidpnt = (xMin + xMax) / 2;
int yMidpnt = (yMin + yMax) / 2;

GLfloat A = zMap[xMin][yMin];
GLfloat B = zMap[xMax][yMin];
GLfloat C = zMap[xMin][yMax];
GLfloat D = zMap[xMax][yMax];

GLfloat E = (A + B + C + D) / 4 + randDisp(disp); // Midpoint height

zMap[xMidpnt][yMidpnt] = E; // Set E

zMap[xMin][yMidpnt] = (A + C + E) / 3 + randDisp(disp);  // F
zMap[xMidpnt][yMin] = (A + B + E) / 3 + randDisp(disp);  // G
zMap[xMax][yMidpnt] = (B + D + E) / 3 + randDisp(disp);  // H
zMap[xMidpnt][yMax] = (C + D + E) / 3 + randDisp(disp);  // I

if ((xMidpnt - xMin) > 1) { // Subdivide if new midpoint length will be > 1

generateLandscapeRec(xMin, xMidpnt, yMin, yMidpnt, nDisp);
generateLandscapeRec(xMidpnt, xMax, yMin, yMidpnt, nDisp);
generateLandscapeRec(xMin, xMidpnt, yMidpnt, yMax, nDisp);
generateLandscapeRec(xMidpnt, xMax, yMidpnt, yMax, nDisp);
}
}

Проблема может быть либо в алгоритме, либо в том, как я выбираю свои очки.

Есть мысли и / или помощь?

0

Решение

Я предполагаю, что вы сталкиваетесь с ошибками округления. Проверка xMidPnt против xMin только для рекурсии не будет работать, если вы используете диапазоны без степеней двух (например, 6×6), и также не будет работать, если ваш диапазон y больше, чем ваш диапазон x. Вместо этого вы захотите использовать 4 условия, по одному на каждый квартал.

if ((xMidpnt - xMin) > 1) || (yMidpnt - yMin > 1))
generateLandscapeRec(xMin, xMidpnt, yMin, yMidpnt, nDisp);
if ((xMidpnt - xMin) > 1) || (yMax - yMidpnt > 1))
gnerateLandscapeRec(xMin, xMidpnt, yMidpnt, yMax, nDisp);
...
1

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

Других решений пока нет …

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