Cette question est venue principalement du désespoir , après avoir passé plusieurs heures à essayer de comprendre le problème.
Si vous jetez vos yeux sur l'image ci-dessus, vous devriez voir que mon algorithme d'algorithme de déplacement de point médian fonctionne (quelque peu) avec succès; en produisant un motif de bruit quelque peu cohérent.
Cependant, il laisse une grille en pointillés noirs sur l'image, et je ne sais pas pourquoi. Je peux prévoir que cela pose problème en mathématiques, mais je ne le vois tout simplement pas; cela n'a pas non plus été signalé dans les ressources en ligne comme un problème possible; donc toute aide sera appréciée pour traquer ce bug.
unsigned char** mdp(unsigned char** base, unsigned base_n, unsigned char r) {
size_t n = (2 * base_n) - 1;
unsigned char** map = new unsigned char*[n];
for (unsigned i = 0; i < n; ++i) map[i] = new unsigned char[n];
// Resize
// 1 0 1
// 0 0 0
// 1 0 1
for (size_t i = 0; i < n; i += 2) {
for (size_t j = !(i % 2 == 0); j < n; j += 2) {
map[i][j] = base[i / 2][j / 2];
}
}
// Diamond algorithm
// 0 0 0
// 0 X 0
// 0 0 0
for (size_t i = 1; i < n; i += 2) {
for (size_t j = 1; j < n; j += 2) {
unsigned char& map_ij = map[i][j];
unsigned char a = map[i - 1][j - 1];
unsigned char b = map[i - 1][j + 1];
unsigned char c = map[i + 1][j - 1];
unsigned char d = map[i + 1][j + 1];
map_ij = (a + b + c + d) / 4;
unsigned char rv = std::rand() % r;
if (map_ij + r < 255) map_ij += rv; // EDIT: <-- thanks! the bug! `map_ij + rv`, not `r`
else map_ij = 255;
}
}
// Square algorithm
// 0 1 0
// 1 0 1
// 0 1 0
for (size_t i = 0; i < n; ++i) {
for (size_t j = (i % 2 == 0); j < n; j += 2) {
unsigned char& map_ij = map[i][j];
// get surrounding values
unsigned char a = 0, b = a, c = a, d = a;
if (i != 0) a = map[i - 1][j];
if (j != 0) b = map[i][j - 1];
if (j + 1 != n) c = map[i][j + 1];
if (i + 1 != n) d = map[i + 1][j];
// average calculation
if (i == 0) map_ij = (b + c + d) / 3;
else if (j == 0) map_ij = (a + c + d) / 3;
else if (j + 1 == n) map_ij = (a + b + d) / 3;
else if (i + 1 == n) map_ij = (a + b + c) / 3;
else map_ij = (a + b + c + d) / 4;
unsigned char rv = std::rand() % r;
if (map_ij + r < 255) map_ij += rv;
else map_ij = 255;
}
}
return map;
}
Si vous avez des conseils ou des ressources autres que http://www.gameprogrammer.com/fractal.html et http://www.lighthouse3d.com/opengl/terrain/index.php?mpd2 pour la génération de terrain basé sur les fractales, je le ferais les apprécier aussi comme commentaires.
Éditer:
C'est la nouvelle image, selon la suggestion de Fabians (ty), mais elle a encore des bizarreries étranges, que vous devriez pouvoir voir tout de suite (petites «fossettes» partout).
Qu'est-ce qui pourrait être à l'origine de ce comportement étrange? Code source mis à jour: http://www.pastie.org/1924223
Éditer:
Un grand merci à Fabian pour avoir trouvé l'erreur de vérification des limites, pour les personnes intéressées, voici la solution actuelle en 512x512 png. Et le code source actuel (modifié par Fabian) .
Edit (des années plus tard): version Python https://gist.github.com/dcousens/5573724#file-mdp-py
la source
Réponses:
L'algorithme ajoute récursivement une valeur, mais la valeur peut être positive ou négative (normalement + -1 / (2 ^ octave))
Si vous commencez à zéro et ajoutez uniquement des valeurs positives, vous ne pouvez que monter, et c'est pourquoi vous voyez les sommets abaissés.
essayez de commencer à 127 plutôt que zéro pour les quatre coins, et essayez également le caractère signé (puis vérifiez vos limites en haut et en bas)
ÉDITER
donc, deux autres choses doivent changer dans le principal (64 >> i) pour obtenir le demi-effet à chaque octave, et aussi votre fonction de sortie (celle qui mappe la finale [] [] tp l'imgdta [], vous venez de besoin de mettre
plutôt que le bloc if else.
une autre chose, je ne sais pas pourquoi, mais votre vérification des limites échoue (c'est les lignes 38 et 65) si vous supprimez complètement la vérification, vous remarquez également de nouveaux blobs sombres, donc je pense que vous devrez peut-être passer à un type plus grand avant de faire les limites, vérifiez si vous voulez l'image la plus bruyante que vous obtenez avec "64 / i".
UNE AUTRE MODIFICATION
vient de découvrir ce que c'était, vous comparez avec «r», pas «rv», dans la vérification des limites. Voici le code fixe: http://pastie.org/1927076
la source
Deux choses qui sautent aux yeux:
Oh, et une chose non algorithmique: je recommande fortement de ne pas faire d'allocations dans votre fonction mdp (); passer dans deux tableaux différents déjà alloués et faire l'itération «sur place», en passant de l'un à l'autre. Si rien d'autre, cela vous permettra de faire du ping-pong d'avant en arrière pendant que vous faites les couches plutôt que d'avoir à allouer un nouveau tableau à chaque fois.
la source
Suite à ce qui précède, vous ne supprimez pas actuellement la mémoire que vous allouez. Pour y remédier, changez la ligne 104 de:
à
et ajoutez ceci après avoir écrit dans le fichier tga:
la source