Pertanyaan ini muncul terutama karena putus asa , setelah menghabiskan beberapa jam mencoba mencari tahu masalahnya.
Jika Anda mengarahkan mata ke gambar di atas, Anda akan melihat bahwa algoritma algoritma perpindahan titik tengah saya berhasil (agak) berhasil; dalam menghasilkan pola kebisingan yang agak koheren.
Namun, itu meninggalkan grid bertitik hitam pada gambar, dan saya tidak tahu mengapa. Saya bisa meramalkan ini menjadi masalah dalam matematika, tetapi saya tidak bisa melihatnya; ini juga tidak ditunjukkan dalam sumber daya online sebagai masalah yang mungkin; jadi bantuan apa pun akan dihargai untuk memburu bug ini.
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;
}
Jika Anda memiliki kiat atau sumber daya selain http://www.gameprogrammer.com/fractal.html dan http://www.lighthouse3d.com/opengl/terrain/index.php?mpd2 untuk pembuatan medan berbasis fraktal, saya akan hargai mereka sebagai komentar juga.
Edit:
Ini adalah gambar baru, sesuai saran Fabian (ty), namun masih memiliki beberapa keanehan aneh, yang seharusnya dapat Anda lihat langsung ('lesung pipit' kecil di mana-mana).
Apa yang bisa menyebabkan perilaku aneh ini? Kode sumber yang diperbarui: http://www.pastie.org/1924223
Edit:
Banyak terima kasih kepada Fabian dalam menemukan kesalahan pemeriksaan batas, bagi mereka yang tertarik, berikut adalah solusi saat ini sebagai 512x512 png. Dan kode sumber saat ini (dimodifikasi oleh Fabian) .
Sunting (tahun kemudian): Versi Python https://gist.github.com/dcousens/5573724#file-mdp-py
sumber
Jawaban:
Algoritma secara rekursif menambahkan nilai, tetapi nilainya bisa positif atau negatif (biasanya + -1 / (2 ^ oktaf))
Jika Anda mulai dari nol dan hanya menambahkan nilai positif, maka Anda hanya bisa naik, dan itulah sebabnya Anda melihat simpul ditarik ke bawah.
coba mulai di 127 daripada nol untuk empat sudut, dan coba juga tanda char (lalu periksa batas Anda baik atas dan bawah)
EDIT
jadi, dua hal lagi perlu diubah di main (64 >> i) untuk mendapatkan setengah efek pada setiap oktaf, dan juga fungsi output Anda (yang memetakan [[] [] tp imgdta [] terakhir, Anda hanya perlu perlu dimasukkan
daripada blok if else.
Hal lain, saya tidak yakin mengapa, tetapi batas Anda gagal (itu garis 38 dan 65) jika Anda menghapus cek sepenuhnya, Anda melihat beberapa gumpalan gelap baru juga, jadi saya rasa Anda mungkin perlu mempromosikan ke tipe yang lebih besar sebelum melakukan batas periksa apakah Anda ingin gambar yang lebih berisik yang Anda dapatkan dengan "64 / i".
EDIT LAIN
baru tahu apa itu, Anda membandingkan terhadap 'r', bukan 'rv', di batas cek. Berikut kode tetapnya: http://pastie.org/1927076
sumber
Dua hal yang muncul:
Oh, dan satu hal non-algoritmik: Saya sangat menyarankan untuk tidak melakukan alokasi dalam fungsi mdp () Anda; lulus dalam dua array yang sudah dialokasikan berbeda dan melakukan iterasi 'di tempat', pergi dari satu ke yang lain. Jika tidak ada yang lain, ini akan memungkinkan Anda melakukan ping-pong bolak-balik saat Anda melakukan layer daripada harus mengalokasikan array baru setiap kali keluar.
sumber
Lebih jauh ke atas, Anda saat ini tidak menghapus memori yang Anda alokasikan. Untuk memperbaiki ini, ubah baris 104 dari:
untuk
dan tambahkan ini setelah menulis ke file tga:
sumber