डायमंड-स्क्वायर इलाके की पीढ़ी की समस्या


11

मैंने इस लेख के अनुसार एक डायमंड-स्क्वायर एल्गोरिदम लागू किया है: http://www.lighthouse3d.com/opengl/terrain/index.php?mpd2

समस्या यह है कि मुझे ये सभी नक्शे में खड़ी चट्टानें मिलती हैं। यह किनारों पर होता है, जब इलाक़ा पुन: विभाजित हो जाता है:

यहाँ छवि विवरण दर्ज करें

यहाँ स्रोत है:

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

}

पैरामीटर: (X1, y1), (x2, y2) - निर्देशांक जो एक ऊंचाई पर एक क्षेत्र को परिभाषित करते हैं (डिफ़ॉल्ट (0,0) (128,128))। रेंज - मूल रूप से अधिकतम। ऊंचाई। (डिफ़ॉल्ट 32)

मदद की बहुत सराहना की जाएगी।


अपने कोड को कठिन देखे बिना, ऐसा लगता है कि आपके पास अंत में 4 पुनरावर्ती कॉलों में गलत कॉल में गलत कोने हैं। नक्शा ऐसा लगता है कि अगले सेट की गणना करने से पहले प्रत्येक वर्ग घुमाया / फ़्लिप किया गया है, इस प्रकार अजीब चट्टानों पर मानचित्र को उप-विभाजित किया गया है। शीर्ष दाएं वर्ग का निचला किनारा ऐसा लगता है कि यह शीर्ष बाएं वर्ग के दाएं किनारे से मेल खाता है, और इसी तरह।
DampeS8N

मुझे नहीं पता तुम्हारा क्या मतलब है। समन्वय प्रणाली का केंद्र शीर्ष बाएं कोने में है, एक्स अक्ष दाईं ओर और नीचे y इंगित करता है। तो पहले पुनरावृति (X1 = 0, y1 = 0) में, (x2 = 128, y2 = 128) और (X1 + hx = 64, y1 + hy = 64) वर्ग का केंद्र है। वर्ग को इस प्रकार 4 उप-वर्गों में विभाजित किया गया है: ((0,0) (64,64)), (64,0) (128,64), ((0,64) (64,128)) और (64,) 64) (128.128))। मुझे ठीक लग रहा है ...
kafka

जवाबों:


12

प्रत्येक उपखंड स्तर में, "स्क्वायर" चरण "डायमंड स्टेप" के परिणामों पर निर्भर करता है। लेकिन यह आसन्न सेल में उत्पादित हीरे-चरण के कारक भी हैं, जिनके लिए आप लेखांकन नहीं कर रहे हैं। मैं DiamondSquare फ़ंक्शन को चौड़ाई-प्रथम को पुन: लिखने के लिए लिखूँगा, बजाय गहराई-पहले के जैसा कि वर्तमान में आपके पास है।

आपका पहला मुद्दा यह है कि चूंकि आप दो बार वर्ग किनारों की फिर से गणना करते हैं, यह आसन्न केंद्र बिंदु के योगदान को नजरअंदाज करता है। उदाहरण के लिए, आपके द्वारा संदर्भित लेख में,

P = (J + G + K + E)/4 + RAND(d)

लेकिन आपका कोड प्रभावी ढंग से करता है

P = (J + G + J + E)/4 + RAND(d)

यह वर्तमान में कारक है केंद्र बिंदु में दो बार , न कि केंद्र बिंदु पर। यही कारण है कि आपको चौड़ाई-पहले जाने की आवश्यकता है, ताकि आपके पास पिछले केंद्र बिंदुओं की गणना हो।

यहाँ मेरा कोड और आउटपुट है:

void DiamondSquare(unsigned x1, unsigned y1, unsigned x2, unsigned y2, float range, unsigned level) {
    if (level < 1) return;

    // diamonds
    for (unsigned i = x1 + level; i < x2; i += level)
        for (unsigned j = y1 + level; j < y2; j += level) {
            float a = m_heightmap[i - level][j - level];
            float b = m_heightmap[i][j - level];
            float c = m_heightmap[i - level][j];
            float d = m_heightmap[i][j];
            float e = m_heightmap[i - level / 2][j - level / 2] = (a + b + c + d) / 4 + GetRnd() * range;
        }

    // squares
    for (unsigned i = x1 + 2 * level; i < x2; i += level)
        for (unsigned j = y1 + 2 * level; j < y2; j += level) {
            float a = m_heightmap[i - level][j - level];
            float b = m_heightmap[i][j - level];
            float c = m_heightmap[i - level][j];
            float d = m_heightmap[i][j];
            float e = m_heightmap[i - level / 2][j - level / 2];

            float f = m_heightmap[i - level][j - level / 2] = (a + c + e + m_heightmap[i - 3 * level / 2][j - level / 2]) / 4 + GetRnd() * range;
            float g = m_heightmap[i - level / 2][j - level] = (a + b + e + m_heightmap[i - level / 2][j - 3 * level / 2]) / 4 + GetRnd() * range;
        }

    DiamondSquare(x1, y1, x2, y2, range / 2, level / 2);
}

http://i.imgur.com/laBhN.png


हाँ, मैं भी पहले-पहले दृष्टिकोण की तर्ज पर सोच रहा था। ये भग्न मुझे हमेशा परेशान कर रहे हैं। पेर्लिन के शोर और एल-सिस्टम के साथ भी ऐसा ही था। तुम कमाल हो।
काफ्का

3

एक संभावना यह है कि आप अपने कार्यान्वयन के साथ एक शॉर्टकट ले रहे हैं जो आपके लिंक किए गए पृष्ठ पर एल्गोरिथ्म नहीं करता है।

वर्ग चरण के लिए, आप के साथ बिंदुओं की ऊंचाई की गणना कर रहे हैं

float f = (a + c + e + e) / 4 + GetRnd() * range;
m_heightmap[x1][y1+hy] = f;

यदि आप अपने नक्शे को लपेट रहे हैं तो पृष्ठ का एल्गोरिथ्म उपयोग करने का संकेत देता है। इससे यह आभास होता है कि आप इस गणना के लिए "अगला वर्ग ओवर" का उपयोग कर रहे हैं। सबसे सरल, पहले मामले में, केंद्रीय बिंदु (ऊंचाई 'ई' के साथ) का उपयोग एफ की गणना करने के लिए बाएं और दाएं दोनों तरफ किया जाता है।

हालाँकि, आपके द्वारा संदर्भित एल्गोरिथ्म में आपके पास इस वर्ग बिंदु की ऊंचाई के मूल्य की गणना करने में मदद करने के लिए अन्य वर्गों / हीरे के वास्तविक मूल्यों का उपयोग होता है। उनके एल्गोरिथ्म में, दूसरे स्तर की गणना निम्न सूत्र से की जाती है:

N = (K + A + J + F)/4 + RAND(d)

वहाँ एक मूल्य के दोहराव की कमी पर ध्यान दें?

मुझे लगता है कि आप दिए गए सूत्रों के गैर-रैपिंग संस्करणों का उपयोग करने के लिए जाने की कोशिश करना चाहते हैं, जो बेहतर पुनरावृत्ति करेंगे, मुझे लगता है।

F = (A + C + E)/3 + ...
    instead of
F = (A + C + E + E)/4 + ...

धन्यवाद, यह एक उपयोगी अवलोकन था। मुझे लगता है कि मैंने अपने घाव को कोडिंग से सीधे नहीं कूदने के लिए सीखा, जब मैं समीकरण देखता हूं।
काफ्का

आपका बहुत - बहुत स्वागत है। मैं अपने आप को बहुत समय करता हूं, भी ... "देखो, कुछ मैं कोड कर सकता हूं। मस्ट कोड। अब!"
18
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.