কোন টাইলগুলি একটি লাইন দ্বারা ছেদ করা হয় তা সন্ধান করে, সেগুলির মধ্য দিয়ে লুপিং বা কোনও এড়িয়ে যাওয়া


10

আমি এখন কয়েক দিন ধরে এই সমস্যাটি দেখছি। আমি এই গ্রাফিকটিকে বিষয়টি কল্পনা করতে সহায়তা করার জন্য জালিয়াতি করেছি: এখানে চিত্র বর্ণনা লিখুন (গ্রাফ থেকে, আমরা জানি যে লাইনটি [1, 1], [1, 2], [2, 2], [2, 3] কে ছেঁটে [ 3,3])

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

সুতরাং, আমার একটি অ্যালগরিদম দরকার যা প্রতিটি গ্রিড স্পেসকে ছেদ করে এমন এক লাইনের সাথে এগিয়ে যাবে। কোন ধারনা?

আমি ব্রেসেনহ্যামের মতো প্রচলিত সাধারণ অ্যালগরিদমগুলি এবং লাইন বরাবর পূর্বনির্ধারিত বিরতিতে পদক্ষেপ নিয়ে একটি কটাক্ষপাত করেছি (দুর্ভাগ্যক্রমে, এই পদ্ধতিটি টাইলগুলি এড়িয়ে যায় যদি তারা পদক্ষেপের আকারের তুলনায় একটি ছোট জোড় দিয়ে ছেদ করে)।

আমি এখন আমার হোয়াইটবোর্ডকে প্রচুর পরিমাণে ফ্লোর () এবং সিল () ফাংশন দিয়ে পপুলেট করছি - তবে এটি অত্যধিক জটিল হয়ে উঠছে এবং আমি আশঙ্কা করছি যে এটি মন্দা হতে পারে।


আপনি ইতিমধ্যে জানেন কীভাবে আসল লাইন-বক্স ছেদটি পরীক্ষা করতে হবে, তাই না? শুধু জিজ্ঞাসা, কারণ এটি উত্তর প্রাসঙ্গিক।
ট্র্যাভিসজি

উত্তর:


6

আপনি যদি ব্লক শুরুর কথা জানেন (আপনি X পয়েন্টটি জানেন এবং ব্লক তালিকায় আপনি [0,1] ব্লকটি অন্তর্ভুক্ত করেন না, সুতরাং আমি মনে করি আপনি প্রারম্ভিক ব্লকটিও জানেন), আমার মনে হয় আপনার অবশ্যই ব্রেসেনহ্যামের অ্যালগরিদম ব্যবহার করা উচিত। আপনি লিখেছেন, আপনি এটি তাকান।

এই সমস্যার জন্য এটি উপযুক্ত অ্যালগরিদম। এটি কোনও উপায়েও লেখা যেতে পারে, এটি কেবল পূর্ণসংখ্যার সাথে গণনা করে। ওয়েবে আপনি প্রচুর বাস্তবায়ন খুঁজে পেতে পারেন।

সম্পাদনা করুন:

আমি দুঃখিত, আমি বুঝতে পারি নি যে ব্রেসেনহ্যাম সমস্ত ব্লক খুঁজে পাবে না। সুতরাং আমি আরও ভাল সমাধান খুঁজে পেয়েছি । সি ++ তেও কোড লেখা আছে তবে আমি মনে করি এটি বুঝতে অসুবিধা হওয়া উচিত নয় :)


1
আমি ব্রেসেনহ্যাম অ্যালগরিদমের অতীতকে দেখার কারণটি কেবল উইকিপিডিয়ায় থাকা চিত্রটির কারণেই হয়েছিল। ( en.wikedia.org/wiki/File:Bresenham.svg ) আপনি দেখতে পাচ্ছেন যে রেখাটি কিছু অংশবিহীন স্কোয়ারকে বিরত করে, যদিও সবেমাত্র। আমার এমন কিছু জিনিস প্রয়োজন যা প্রতিটি টাইল সনাক্ত করতে পারে , যতই না কাটা কাটা ছোট ছোট ফল নির্বিশেষে। সম্পাদনা: দেখা যাচ্ছে যে আমি যাইহোক ব্রেনহ্যামের ভুল বুঝেছি। আমার এটির বিপরীতমুখী হওয়া দরকার - আমার প্রথম এবং শেষ পয়েন্ট রয়েছে এবং আমার এটি টাইলসটি ছেদ করতে পারে - এটির চেয়ে ভাল যে লাইনের চক্রান্ত করা ভাল।
সুডস

@ জাস্টসডস: পোস্টে আপডেটের জন্য চেক করুন।
জাকারমার্জ

আরে আরে! আমার হোয়াইটবোর্ডে যা আছে তা প্রায় সরাসরি মেলে! ধন্যবাদ, আমার সিস্টেমটি এখন বাস্তবায়িত এবং কাজ করছে। :-)
সাবানফেনা

প্রশ্নটির উত্তর না পাওয়ায় আপনি ব্রেসেনহ্যামের অ্যালগরিদম সম্পর্কে অংশটি সরাতে পারেন? চিন্তা করবেন না, এটি আপনার উত্তরের সম্পাদনার ইতিহাসে থাকবে।
জেনিথ

1

উদাহরণ হিসাবে কোডটি স্বীকৃত উত্তরটির সাথে লিঙ্কটির সঠিকভাবে তির্যক রেখার জন্য কিছু সমন্বয় প্রয়োজন। এখানে কিউটি (সি ++ এবং কিউএমএল) দিয়ে লেখা একটি সম্পূর্ণ ডেমো অ্যাপ্লিকেশন।

গ্রিড লাইন ছেদ

প্রাসঙ্গিক সি ++ কোড:

void rayCast()
{
    if (!isComponentComplete())
        return;

    mTiles.clear();
    mTiles.fill(QColor::fromRgb(255, 222, 173), mSizeInTiles.width() * mSizeInTiles.height());

    const QPoint startTile = startTilePos();
    const QPoint endTile = endTilePos();
    // http://playtechs.blogspot.com/2007/03/raytracing-on-grid.html
    int x0 = startTile.x();
    int y0 = startTile.y();
    int x1 = endTile.x();
    int y1 = endTile.y();

    int dx = abs(x1 - x0);
    int dy = abs(y1 - y0);
    int x = x0;
    int y = y0;
    int n = 1 + dx + dy;
    int x_inc = (x1 > x0) ? 1 : -1;
    int y_inc = (y1 > y0) ? 1 : -1;
    int error = dx - dy;
    dx *= 2;
    dy *= 2;

    for (; n > 0; --n)
    {
        visit(x, y);

        if (error > 0)
        {
            x += x_inc;
            error -= dy;
        }
        else if (error < 0)
        {
            y += y_inc;
            error += dx;
        }
        else if (error == 0) {
            // Ensure that perfectly diagonal lines don't take up more tiles than necessary.
            // http://playtechs.blogspot.com/2007/03/raytracing-on-grid.html?showComment=1281448902099#c3785285092830049685
            x += x_inc;
            y += y_inc;
            error -= dy;
            error += dx;
            --n;
        }
    }

    update();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.