মিডপয়েন্ট ডিসপ্লেসমেন্ট অ্যালগরিদম


14

এমডিপিএমডিপি

এই সমস্যাটি বেশিরভাগ সময় সমস্যাটি সনাক্ত করার চেষ্টা করার পরে, নিখুঁত হতাশার বাইরে এসেছিল ।

যদি আপনি উপরের ছবিটিতে চোখ রাখেন তবে আপনার দেখতে হবে যে আমার মিডপয়েন্ট ডিসপ্লেসমেন্ট অ্যালগরিদম অ্যালগরিদম সফলভাবে কাজ করছে (কিছুটা) সফলভাবে; কিছুটা সুসংগত শব্দ প্যাটার্ন উত্পাদন করতে।

যাইহোক, এটি চিত্রটিতে একটি কালো বিন্দুযুক্ত গ্রিড রেখে যাচ্ছে এবং কেন তা আমার কোনও ধারণা নেই। আমি এটি গণিতে একটি সমস্যা হওয়ার পূর্বেই ধারণা করতে পারি, তবে আমি এটি দেখতে পাচ্ছি না; এটি কোনও সম্ভাব্য সমস্যা হিসাবে কোনও অনলাইন সংস্থায়ও চিহ্নিত করা হয়নি; সুতরাং এই বাগটি শিকার হিসাবে কোনও সহায়তা প্রশংসিত হবে।

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;
}

ফ্র্যাক্টাল ভিত্তিক ভূখণ্ড প্রজন্মের জন্য আপনার কাছে যদি http://www.gameprogrammer.com/fractal.html এবং http://www.lightthouse3d.com/opengl/terrain/index.php?mpd2 ব্যতীত কোনও টিপস বা সংস্থান থাকে তবে আমি চাই মন্তব্য হিসাবে তাদের প্রশংসা।

সম্পাদনা:

এমডিপি

ফ্যাবিয়ানদের পরামর্শ অনুসারে এটিই নতুন চিত্র t তবে এটিতে এখনও কিছু অদ্ভুত স্নিগ্ধতা রয়েছে যা আপনি সরাসরি দেখতে পাবেন (ছোট 'ডিম্পলগুলি' সর্বত্র)।

এই অদ্ভুত আচরণের কারণ কী হতে পারে? আপডেট হওয়া উত্স কোড: http://www.pastie.org/1924223

সম্পাদনা:

সীমিত চেক ত্রুটিটি খুঁজে পেতে ফ্যাবিয়ানকে অনেক ধন্যবাদ, আগ্রহীদের জন্য, এখানে বর্তমান সমাধানটি 512x512 পিএনজি হিসাবে দেওয়া হয়েছে। এবং বর্তমান উত্স কোড (ফ্যাবিয়ান দ্বারা সংশোধিত)এমডিপি

সম্পাদনা করুন (বছর পরে): পাইথন সংস্করণ https://gist.github.com/dcousens/5573724#file-mdp-py


ছবিগুলিতে দেখে মনে হচ্ছে যে প্রতিটি বিন্দু একই উচ্চতায় রয়েছে। কোণগুলিও কি একই উচ্চতায় রয়েছে?
deft_code

1
এটি মূল্যবান জন্য, আপনার চিত্রগুলি দেখতে খুব সুন্দর দেখাচ্ছে। :)
ক্রিস

স্ক্রান্ড (): আমি পুরোপুরি নিশ্চিত নই যে আমি বুঝতে পেরেছি - এই অন্তরালে একটি স্বাক্ষরযুক্ত চরিত্রটি ফেরত দেওয়ার কথা রয়েছে (-r / 2, r / 2]? ডিম্পলগুলি, যাইহোক আমার কাছে, ফলাফলের মতো মনে হয় উপরি প্রবাহিত: পার্শ্ববর্তী অঞ্চলগুলি হঠাৎ কালো রঙের অঙ্কুরিত হবে বলে মনে হচ্ছে এবং আবার সাদা পর্যন্ত উঠে গেল rall সামগ্রিকভাবে, এটির মতো মনে হচ্ছে ধারালো ব্যান্ডিং রয়েছে, আবারও আমাকে পরামর্শ দিয়েছিল যে আপনি সম্ভবত উপচে চলেছেন সম্ভবতঃ আপনি কি গণিতে কোনও বিষয়ে আপত্তি করতে মন চান? উচ্চতর নির্ভুলতা (বলুন, পূর্ণসংখ্যা), এবং তারপরে [0,256] বা [-128,127] মানগুলিতে বাতা দেওয়া?
ChrisE

সমস্যাটি নীচে সমাধান করা হয়েছিল, কারণ এটি এলোমেলো মানের প্রকৃত মানের চেয়ে নয় বরং এলোমেলো মানের পরিসীমাটির বিরুদ্ধে আমি সীমাবদ্ধ ছিল। Scrand () একটি অস্থায়ী 'গোলমাল' ফাংশনটি আদর্শভাবে ফেরার ছিল [-128, 127]
deceleratedcaviar

আহ! এখন এটি কাজ করে শুনে খুব ভাল লাগল।
ক্রিসই

উত্তর:


12

অ্যালগরিদম পুনরাবৃত্তভাবে একটি মান যোগ করে, তবে মানটি ধনাত্মক বা নেতিবাচক হতে পারে (সাধারণত + -1 / (2 oc অক্টোবর))

আপনি যদি শূন্য থেকে শুরু করেন এবং কেবল ইতিবাচক মানগুলি যোগ করেন তবে আপনি কেবল উপরে যেতে পারেন, এবং এজন্যই আপনি শীর্ষগুলি নীচে টানতে দেখছেন।

চার কোণার শূন্যের পরিবর্তে 127 থেকে শুরু করার চেষ্টা করুন এবং স্বাক্ষর করা চরটিও চেষ্টা করুন (তারপরে আপনার সীমানা উপরে এবং নীচে উভয়টি পরীক্ষা করে দেখুন)

সম্পাদনা

সুতরাং, প্রতিটি অষ্টভরে অর্ধেক প্রভাব পেতে মূল (>>৪ >> আমি) আরও দুটি জিনিস বদলাতে হবে এবং আপনার আউটপুট ফাংশনও (চূড়ান্ত মানচিত্রের যেটি []] টিপি ইমজিডিটি [], আপনি কেবল লাগাতে হবে

imgdta [(আমি * এন) + জ] = 128 + চূড়ান্ত [i] [জে];

বরং অন্য যদি ব্লক।

অন্য একটি জিনিস, আমি কেন তা নিশ্চিত নই, তবে আপনার সীমানা পরীক্ষা ব্যর্থ হচ্ছে (এটি লাইন 38 এবং 65) আপনি যদি চেকটি পুরোপুরি সরিয়ে ফেলেন তবে আপনি কিছু নতুন গা dark় ব্লবও লক্ষ্য করেন, সুতরাং আমি মনে করি আপনাকে আরও বড় ধরণের প্রচারের প্রয়োজন হতে পারে সীমাবদ্ধতা পরীক্ষা করার আগে আপনি "64 / i" এর সাথে আরও কোলাহলপূর্ণ ছবি পেতে চান কিনা তা পরীক্ষা করে দেখুন।

অন্য সম্পাদনা

সবেমাত্র এটি কী ছিল তা আপনি সীমানার চেকটিতে 'আরভি' নয়, 'আরভি' এর সাথে তুলনা করছেন। এখানে স্থির কোডটি রয়েছে: http://pastie.org/1927076


এটি নির্বিঘ্নে এটি যাওয়ার আরও ভাল উপায় ছিল, তবে এখনও পর্যন্ত কোনও সিগার নেই, এটি আমার চিত্রটিতে এখনও কিছু 'কোরিক' রয়েছে বলে মনে হয়, আমি মূল পোস্টটি আপডেট করেছি।
deceleratedcaviar

নিশ্চিত নয় তবে লাইনের wrong৩ টি ভুল দেখাচ্ছে, /৪ / আমার প্রয়োজন হতে পারে >>৪ >> আমি (প্রতিটি অর্ধেক প্রভাব হিসাবে আপনি)
রিচার্ড ফ্যাবিয়ান

আহহহ !! আপনাকে অনেক ধন্যবাদ, আমি বিশ্বাস করতে পারি না, আমি জানতাম যে এটি দ্বিতীয় সমস্যার জন্য বোকামি কিছু হবে। আপনার অস্থায়ী টিজিএ কোডটি পছন্দ হয়েছে, দুঃখিত, আমি আপনাকে ঝামেলা বাঁচিয়ে শিরোনামটি রেখে দিয়েছি।
deceleratedcaviar

3

দুটি জিনিস যা বাইরে চলে যায়:

  1. ফিক্স-পয়েন্টে এটি করার জন্য আপনার কাছে কোন বাধ্যতামূলক কারণ আছে? প্রতি সেটের সাথে এটিতে কোনও ভুল নেই, এবং এটি ব্যবহারের প্রচুর কারণ রয়েছে (বিশেষত মেমরির প্রয়োজনীয়তা যদি আপনি একটি বিশাল মানচিত্রের দিকে এগিয়ে যাওয়ার পরিকল্পনা করেন) তবে আমি অবশ্যই অ্যালগরিদমের ভাসমান-পয়েন্ট সংস্করণ দিয়ে শুরু করব এবং এটি কাজ করার পরে এটি নির্দিষ্ট পয়েন্টে রূপান্তর করুন; এটি, অন্য কিছু না হলে, ত্রুটিগুলির একটি প্রশংসনীয় উত্সকে মুছে ফেলা উচিত (বিশেষত, আমি সন্দেহ করি যে আপনার ক্ল্যাম্পিংয়ের ফলে সমস্যা দেখা দিতে পারে এবং কখন / সাবট্র্যাক্ট আরভি যুক্ত করার শর্ত রয়েছে)।
  2. যদিও আমি যে কোডটি দেখছি তা থেকে জানা শক্ত, আপনার রা্যান্ডমাইজড উচ্চতার স্থানচ্যুতিটি স্তরের সাথে স্কেলিংয়ের মতো বলে মনে হচ্ছে না এবং (1) এ সমস্যার সাথে মিলিত হওয়ার ফলে কিছু সমস্যা হতে পারে - আপনার হওয়া উচিত নয় প্রতিটি স্তরে একই পরিমাণ দ্বারা স্থানচ্যুতি।

ওহ, এবং একটি অ অ্যালগোরিদমিক জিনিস: আমি দৃ strongly়ভাবে আপনার এমডিপি () ফাংশনে বরাদ্দ না করার পরামর্শ দিচ্ছি; ইতিমধ্যে বরাদ্দ থাকা দুটি ভিন্ন অ্যারেতে পাস করুন এবং এক থেকে অন্যটিতে গিয়ে 'ইন-প্লেস' পুনরাবৃত্তি করুন। যদি আর কিছুই না হয় তবে প্রতিবার নতুন অ্যারে বরাদ্দ না করে স্তরগুলি করার কারণে এটি আপনাকে পিছনে পিছনে ফেলে দেবে।


কিছু ভাল পয়েন্ট, স্পষ্টতই আমি কেবল অ্যালগরিদমকে সঠিক করার চেষ্টা করছি, বাস্তবায়ন আদর্শের থেকে অনেক দূরে, আমি এই মুহুর্তে স্মৃতিও পরিষ্কার করি না: পি।
মিথ্যাচারিত

এই মুহুর্তে, পাসের উপরের স্কেলিংটি 64 / i হয়, সম্ভবত আমি পরে এটি পরিবর্তন করব, তবে এটি বর্তমানে অভিজ্ঞ ডিম্পলসের প্রভাবটি ব্যাখ্যা করে না। : এস
ডিসলেরেটকাভিয়ার

0

উপরের দিক থেকেও আপনি বর্তমানে বরাদ্দ করা মেমরিটি মুছে ফেলছেন না। এটির প্রতিকারের জন্য 104 লাইনটি পরিবর্তন করুন:

for (unsigned i = 1; i < 6; ++i) final = mdp(final, n, 64 / i);

প্রতি

for (unsigned i = 1; i < 6; ++i) {
  signed char** new_final = mdp(final, n, 64 / i);
  for (unsigned i = 0; i < n; ++i)
    delete[] final[i];
  delete[] final;
  final = new_final;
}

এবং টিগা ফাইলটিতে লেখার পরে এটি যুক্ত করুন:

for (unsigned i = 0; i < n; ++i)
  delete[] final[i];
delete[] final;

আমি কীভাবে স্মৃতি পরিষ্কার করতে পারি সে সম্পর্কে আমি খুব সচেতন, তবে এটি কেবল একটি অ্যালগরিদম প্রোটোটাইপ হিসাবে দেখা এবং ভেক্টরগুলি ব্যবহার করার জন্য এটি পুনরায় লেখা হবে, আমি ঠিক এটি নিশ্চিত করতে চেয়েছিলাম it
মিথ্যাচারিত
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.