Saya telah menerapkan algoritma berlian-persegi sesuai dengan artikel ini: http://www.lighthouse3d.com/opengl/terrain/index.php?mpd2
Masalahnya adalah saya mendapatkan tebing curam ini di seluruh peta. Ini terjadi di tepian, saat medan dibagi secara rekursif:
Inilah sumbernya:
void DiamondSquare(unsigned x1,unsigned y1,unsigned x2,unsigned y2,float range)
{
int c1 = (int)x2 - (int)x1;
int c2 = (int)y2 - (int)y1;
unsigned hx = (x2 - x1)/2;
unsigned hy = (y2 - y1)/2;
if((c1 <= 1) || (c2 <= 1))
return;
// Diamond stage
float a = m_heightmap[x1][y1];
float b = m_heightmap[x2][y1];
float c = m_heightmap[x1][y2];
float d = m_heightmap[x2][y2];
float e = (a+b+c+d) / 4 + GetRnd() * range;
m_heightmap[x1 + hx][y1 + hy] = e;
// Square stage
float f = (a + c + e + e) / 4 + GetRnd() * range;
m_heightmap[x1][y1+hy] = f;
float g = (a + b + e + e) / 4 + GetRnd() * range;
m_heightmap[x1+hx][y1] = g;
float h = (b + d + e + e) / 4 + GetRnd() * range;
m_heightmap[x2][y1+hy] = h;
float i = (c + d + e + e) / 4 + GetRnd() * range;
m_heightmap[x1+hx][y2] = i;
DiamondSquare(x1, y1, x1+hx, y1+hy, range / 2.0); // Upper left
DiamondSquare(x1+hx, y1, x2, y1+hy, range / 2.0); // Upper right
DiamondSquare(x1, y1+hy, x1+hx, y2, range / 2.0); // Lower left
DiamondSquare(x1+hx, y1+hy, x2, y2, range / 2.0); // Lower right
}
Parameter: (x1, y1), (x2, y2) - koordinat yang menentukan suatu wilayah pada peta ketinggian (default (0,0) (128.128)). kisaran - pada dasarnya maks. tinggi. (default 32)
Bantuan akan sangat dihargai.
Jawaban:
Di setiap tingkat pembagian, langkah "kuadrat" bergantung pada hasil "langkah berlian". Tapi itu juga faktor dalam langkah berlian yang diproduksi di sel yang berdekatan, yang tidak Anda perhitungkan. Saya akan menulis ulang fungsi DiamondSquare untuk beralih Breadth-first, bukan depth-first seperti yang Anda miliki saat ini.
Masalah pertama Anda adalah karena Anda menghitung ulang tepi persegi dua kali, itu mengabaikan kontribusi titik pusat yang berdekatan. Misalnya, dalam artikel yang Anda referensi,
tetapi kode Anda efektif
yaitu faktor di titik tengah saat ini dua kali, bukan titik tengah yang berdekatan. Inilah sebabnya mengapa Anda harus pergi dulu, sehingga Anda memiliki titik tengah sebelumnya dihitung.
Ini kode saya dan hasilnya:.
sumber
Satu kemungkinan adalah Anda mengambil jalan pintas dengan implementasi Anda yang tidak dimiliki algoritma pada halaman yang ditautkan.
Untuk tahap kuadrat, Anda menghitung ketinggian poin dengan
dimana algoritma halaman menunjukkan untuk digunakan jika Anda membungkus peta Anda. Ini memberi kesan bahwa Anda menggunakan nilai tinggi "kuadrat berikutnya" untuk menghitung yang satu ini. Dalam kasus paling sederhana, pertama, titik pusat (dengan tinggi 'e') digunakan pada sisi kiri dan kanan untuk menghitung f.
Namun, algoritma yang Anda referensikan telah Anda gunakan nilai aktual dari kuadrat lain / berlian untuk membantu Anda menghitung nilai ketinggian titik persegi ini. Dalam algoritme mereka, titik level kedua dihitung dengan rumus berikut:
Perhatikan kurangnya duplikasi nilai di sana?
Saya pikir Anda mungkin ingin mencoba menggunakan versi non-pembungkus formula yang diberikan, itu akan muncul kembali dengan lebih baik, saya pikir.
sumber