হীরা-বর্গক্ষেত্র ভূখণ্ডের উত্পাদন সমস্যা


11

আমি এই নিবন্ধ অনুযায়ী একটি হীরা-বর্গাকার অ্যালগরিদম প্রয়োগ করেছি: http://www.lightthouse3d.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 পুনরাবৃত্ত কলগুলিতে ভুল কলের মধ্যে সম্ভবত ভুল কোণ রয়েছে। মানচিত্রটি দেখে মনে হচ্ছে যে প্রতিটি বর্গক্ষেত্রটি পরবর্তী সেটটি গণনা করার আগে ঘোরানো / উল্টানো হয়েছে, এইভাবে অদ্ভুত ক্লিফগুলিতে মানচিত্রটিকে বিভক্ত করে। উপরের ডান বর্গাকার নীচের প্রান্তটি দেখে মনে হচ্ছে এটি শীর্ষ বাম স্কোয়ারের ডান প্রান্তের সাথে মিলে যায়।
ড্যাম্প এস

আপনি কি বোঝাতে চাচ্ছেন তা আমি নিশ্চিত নই. স্থানাঙ্ক ব্যবস্থার কেন্দ্রটি উপরের বাম কোণে, এক্স অক্ষটি ডানদিকে এবং 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))। আমার কাছে দুর্দান্ত দেখাচ্ছে ...
কাফকা

উত্তর:


12

প্রতিটি মহকুমা স্তরে, "স্কোয়ার" পদক্ষেপটি "হীরা পদক্ষেপ" এর ফলাফলের উপর নির্ভর করে। তবে এটি সংলগ্ন ঘরে উত্পাদিত হীরা-পদক্ষেপেরও কারণ রয়েছে, যার জন্য আপনি অ্যাকাউন্টিং করছেন না। আমি বর্তমানে ডায়মন্ডস্কয়ার ফাংশনটি পুনরায় লিখতে চাইছি তবে আপনার বর্তমানে গভীরতা-প্রথমের পরিবর্তে প্রথম প্রস্থের পুনরাবৃত্তি করতে হবে।

আপনার প্রথম সমস্যাটি হ'ল যেহেতু আপনি বর্গাকার প্রান্তগুলি পুনরায় গণনা করছেন, এটি সংলগ্ন কেন্দ্রবিন্দুটির অবদানকে উপেক্ষা করে। উদাহরণস্বরূপ, আপনি যে নিবন্ধটি উল্লেখ করেছেন তাতে

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 + ...

ধন্যবাদ, এটি একটি সহায়ক পর্যবেক্ষণ ছিল। আমি মনে করি যে আমি যখন আমার সমীকরণগুলি দেখি তখন সরাসরি কোডিংয়ে না to
কাফকা

আপনি বেশ স্বাগতম। আমি নিজেও অনেক সময় এটি করি ... "দেখুন, আমি কোড করতে পারি এমন কিছু Must অবশ্যই, কোড। এখন!"
fnord
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.