Я пытаюсь реализовать алгоритм генерации рельефа алмазного квадрата в OpenGL.
Пока у меня есть 2D-плоскость (фактически 3D, но все координаты Z установлены на 0), состоящая из 1024 различных квадратов. Координаты организованы в 2-мерные массивы
У нас есть, например:
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);
}
}
Проблема может быть либо в алгоритме, либо в том, как я выбираю свои очки.
Есть мысли и / или помощь?
Я предполагаю, что вы сталкиваетесь с ошибками округления. Проверка 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);
...
Других решений пока нет …