আমি কীভাবে এক্সএনএ তে ষড়ভুজ টাইলম্যাপ বাছাই বাস্তবায়ন করতে পারি?


13

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

কেউ কি জানেন যে পুরো জিনিসটিকে জটিল না করে আমি ষড়ভুজটি ক্লিক করা হয়েছে কিনা তা পরীক্ষা করে কীভাবে যেতে পারি?

উত্তর:


13

এই ছবিটি একবার দেখুন

ষড়ভুজ পচে যাওয়া

আপনি দেখতে পাচ্ছেন যে x, y আয়তক্ষেত্রাকার স্থানাঙ্ক ব্যবস্থা মানচিত্রের ষড়্ভুজাকারে তুলনামূলকভাবে স্বজ্ঞাত উপায় আছে।

আমরা "রেট" অনিয়মিত হেক্সাগন, অর্থাৎ উপবৃত্তাগুলিতে লিখিত হেক্সাগন বা নিয়মিত হেক্সাগন থেকে প্রাপ্ত উভয় দিকের তুলনামূলকভাবে উভয় দিকেই মাপসই করা (rotালাই-শিয়ারিং নেই) about

একটি আয়তাকার ষড়্ভুজটি সংক্ষিপ্ত আয়তক্ষেত্রের দৈর্ঘ্য এবং ইনসিলিঙ্কিংয়ের প্রস্থের প্রস্থ দ্বারা সংজ্ঞায়িত করা যেতে পারে। (ওয়াট, পঃ, জ)

আয়তক্ষেত্রগুলি এনক্রিট / সংক্ষিপ্তকরণ

ষড়ভুজ সূচকটি সন্ধান করার সহজ উপায়টি স্থানটিকে নিম্নলিখিত হিসাবে বিভাজন করা:

স্থান বিভাজন

আয়তক্ষেত্রের প্রস্থ w + (W - w) / 2 = (w + W) / 2, এর উচ্চতা h / 2; সবুজ আয়তক্ষেত্রের প্রস্থ (WW) / 2। কোথায় আয়তক্ষেত্রটি বিন্দুতে পড়ে তা সন্ধান করা সহজ:

এখানে চিত্র বর্ণনা লিখুন

u এবং v হ'ল অনুস্মারক স্থানাঙ্ক যা নির্দেশ করে যে বিন্দুটি i, j আয়তক্ষেত্রের মধ্যে কোথায় রয়েছে: ডাব্লু ব্যবহার করে আমরা বলতে পারি আমরা সবুজ অঞ্চলে (ইউ <(ডাব্লুডাব্লু) / 2) থাকি বা না থাকি।

যদি এটি হ'ল আমরা সবুজ অঞ্চলে থাকি তবে আমাদের জানতে হবে যে আমরা ষড়্ভুজের উপরের বা নিম্ন অর্ধে আছি কি না: আমি এবং জে উভয়ই সমান বা দুটি বিজোড় হলে আমরা উপরের অর্ধে থাকি; আমরা অন্যথায় নিম্ন অর্ধেক হয়।

উভয় ক্ষেত্রেই ইউ এবং ভি ট্র্যাসফর্ম করা উপযোগী যাতে তারা 0 এবং 1 এর মধ্যে পরিবর্তিত হয়:

এখানে চিত্র বর্ণনা লিখুন

আমরা যদি নীচের অর্ধেক এবং v <u হয়

অথবা

যদি আমরা উপরের অর্ধে এবং (1-v)> ইউ হয়

তাহলে আমরা একে একে হ্রাস করব

এখন আমাদের কেবল জে হ্রাস করতে হবে যদি আমি দেখতে দেখতে যে আমি অনুভূমিক ষড়্ভুজ সূচক (কলাম) এবং জে / 2 এর পূর্ণসংখ্যা অংশটি উল্লম্ব ষড়ভুজ সূচক (সারি)

এখানে চিত্র বর্ণনা লিখুন


ধন্যবাদ! সত্যিই সহায়ক, সবুজ বিভাগের বিভাজন নিয়ে কিছু সমস্যা দেখা দিয়েছে (আমি কি আমি 1 বা 1 থেকে বিয়োগ করব) তবে আমার মনে হয় এটি আমার হেক্সাগনগুলির ওরিয়েন্টেশনের কারণে হয়েছিল। সব কাজ, ধন্যবাদ!
জোয়েল

14

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

এখানে একটি ষড়ভুজ এর পরামিতি রয়েছে। এর কেন্দ্রটি অবস্থিত O, বৃহত্তম প্রস্থটি 2a, উচ্চতা 2bএবং শীর্ষ প্রান্তের দৈর্ঘ্য 2c

         Y ^
           |
       ____|____
      /  b |   |\
     /     |   | \
    /      |   |  \
---(-------+---+---)------>
    \     O|   c  / a      X
     \     |     /
      \____|____/
           |

এটি নীচের বাম ষড়ভুজ কেন্দ্রে উত্স সহ সারি / কলাম লেআউট। যদি আপনার সেটআপটি আলাদা (x,y)হয় তবে এই ক্ষেত্রে পিছিয়ে পড়তে আপনার স্থানাঙ্কগুলি অনুবাদ করুন বা উদাহরণস্বরূপ -yপরিবর্তে ব্যবহার করুন y:

col 0
 | col 1
 |   | col 2
 |   |  |
 __  | __    __    __    __   
/  \__/  \__/  \__/  \__/  \__
\__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/_ _ line 2
\__/  \__/  \__/  \__/  \__/  \ _ _ _ line 1
/ .\__/  \__/  \__/  \__/  \__/_ _ line 0
\__/  \__/  \__/  \__/  \__/

নীচের কোডটি পরে আপনাকে ষড়ভুজটির সারি এবং কলামটি পয়েন্ট সহ দেবে (x,y):

static void GetHex(float x, float y, out int row, out int column)
{
  // Find out which major row and column we are on:
  row = (int)(y / b);
  column = (int)(x / (a + c));

  // Compute the offset into these row and column:
  float dy = y - (float)row * b;
  float dx = x - (float)column * (a + c);

  // Are we on the left of the hexagon edge, or on the right?
  if (((row ^ column) & 1) == 0)
      dy = b - dy;
  int right = dy * (a - c) < b * (dx - c) ? 1 : 0;

  // Now we have all the information we need, just fine-tune row and column.
  row += (column ^ row ^ right) & 1;
  column += right;
}

উপরের কোডটি এই আইডিয়ো রানটিতে নিখুঁত হেক্সাগন আঁকতে পারে তা আপনি পরীক্ষা করতে পারেন ।


আমি প্রথমবার আইডাউন সম্পর্কে শুনেছি, তবে এটি সত্যিই দরকারী বলে মনে হচ্ছে!
ডেভিড গওভিয়া

@ ডেভিডলুজগুভিয়া: হ্যাঁ, এটি দুর্দান্ত। আমি ওয়েব বা ক্লাউড পরিষেবায় পছন্দ করি না তবে এটি সহায়ক is
sam hocevar

1

ষড়ভুজের ক্ষেত্রের ভিতরে আপনি 3 টি ঘোরানো আয়তক্ষেত্রগুলি ফিট করতে পারেন এবং সঠিকভাবে করা গেলে এটি অঞ্চলটি পুরোপুরি পূরণ করবে। তাহলে এটি কেবল তিনটি আয়তক্ষেত্রের সংঘর্ষের জন্য পরীক্ষা করার বিষয় হবে।


1

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

উপরের কাজটি করার জন্য, আপনি সমস্ত হেক্সাসের কেন্দ্রগুলি সহজেই প্লট করতে পারেন এবং তারপরে সমস্ত হেক্সসের বিমানটিতে ক্লিক করার পরে মাউসের নিকটতম একটিটি সন্ধান করতে পারেন। টেসলেলেটেড হেক্সাগনগুলির একটি বিমানের নিকটতম কেন্দ্রটি আপনি সর্বদা ঘুরে বেড়াচ্ছেন one


1

আমি ইতিমধ্যে একটি অনুরূপ প্রশ্নের উত্তর দিয়েছি, অভিন্ন লক্ষ্য নিয়ে, স্ট্যাক ওভারফ্লোতে আমি এটি দৃin়তার জন্য এখানে আবার পোস্ট করব: (এনবি - সমস্ত কোড জাভাতে লেখা এবং পরীক্ষিত)

ওভারলেয়েড স্কোয়ার গ্রিড সহ ষড়ভুজীয় গ্রিড

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

সমাধানটি এখন কোনও পয়েন্টের কোন বাক্সে রয়েছে তা সন্ধান করার মতো সহজ, তারপরে বিন্দুটি কোনও ত্রিভুজগুলির মধ্যে রয়েছে কিনা তা পরীক্ষা করে দেখুন, এবং প্রয়োজনে উত্তরটি সংশোধন করুন।

private final Hexagon getSelectedHexagon(int x, int y)
{
    // Find the row and column of the box that the point falls in.
    int row = (int) (y / gridHeight);
    int column;

    boolean rowIsOdd = row % 2 == 1;

    // Is the row an odd number?
    if (rowIsOdd)// Yes: Offset x to match the indent of the row
        column = (int) ((x - halfWidth) / gridWidth);
    else// No: Calculate normally
        column = (int) (x / gridWidth);

আমাদের বিন্দুতে বাক্সটির সারি এবং কলাম রয়েছে এই মুহুর্তে, আমাদের ষড়ভুজের দুটি শীর্ষ প্রান্তের বিপরীতে আমাদের পয়েন্টটি পরীক্ষা করে দেখতে হবে যে আমাদের বিন্দু উপরের ষড়্ঘে কোনওর মধ্যে রয়েছে কিনা:

    // Work out the position of the point relative to the box it is in
    double relY = y - (row * gridHeight);
    double relX;

    if (rowIsOdd)
        relX = (x - (column * gridWidth)) - halfWidth;
    else
        relX = x - (column * gridWidth);

আপেক্ষিক সমন্বয় থাকা পরবর্তী পদক্ষেপটি আরও সহজ করে তোলে।

একটি সরলরেখার জন্য জেনেরিক সমীকরণ

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

    // Work out if the point is above either of the hexagon's top edges
    if (relY < (-m * relX) + c) // LEFT edge
        {
            row--;
            if (!rowIsOdd)
                column--;
        }
    else if (relY < (m * relX) - c) // RIGHT edge
        {
            row--;
            if (rowIsOdd)
                column++;
        }

    return hexagons[column][row];
}

উপরের উদাহরণে ব্যবহৃত ভেরিয়েবলগুলির দ্রুত ব্যাখ্যা:

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

মিটি গ্রেডিয়েন্ট, সুতরাং এম = সি / অর্ধপথ


উপরোক্তভাবে নিওশামের সংযোজন

এটি সেবাস্তিয়ান ট্রয়ের উত্তরের একটি সংযোজন। আমি এটিকে একটি মন্তব্য হিসাবে রেখে দেব তবে আমি এখনও যথেষ্ট খ্যাতি পাই না।

আপনি যদি এখানে বর্ণিত হিসাবে অক্ষীয় সমন্বয় ব্যবস্থা বাস্তবায়ন করতে চান: http://www.redblobgames.com/grids/hexagons/

আপনি কোডটিতে কিছুটা পরিবর্তন করতে পারেন।

পরিবর্তে

// Is the row an odd number?
if (rowIsOdd)// Yes: Offset x to match the indent of the row
    column = (int) ((x - halfWidth) / gridWidth);
else// No: Calculate normally
    column = (int) (x / gridWidth);

এটা ব্যবহার কর

float columnOffset = row * halfWidth;
column = (int)(x + columnOffset)/gridWidth; //switch + to - to align the grid the other way

এটি স্থানাঙ্ক (0, 2) সরাসরি (0, 0) নীচে না হয়ে (0, 0) এবং (0, 1) হিসাবে একই তির্যক কলামে থাকবে।


আমি বুঝতে পেরেছি যে এটি হেক্সাগনগুলির মধ্যে ফাঁকগুলি বিবেচনা করে না তবে এটি আপনার সমস্যাটিকে যথেষ্ট সঙ্কুচিত করতে সহায়তা করবে।
ট্রয়সিফ

0

যদি আপনার সমস্ত হেক্সাগন একই অনুপাত এবং স্থাপন করে তৈরি করা হয় তবে আপনি সংঘর্ষের জন্য কিছু ধরণের ওভারলে সম্পদ ব্যবহার করতে পারেন, এর লাইন বরাবর এমন কিছু: ষড়ভুজের জন্য সংঘর্ষের ওভারলে

তারপরে, আপনাকে যা করতে হবে তা হ'ল সংঘর্ষের চিত্রটি যেখানে আপনার ষড়্ভুজটি রয়েছে, বাম কোণার সাথে সম্পর্কিত মাউস অবস্থানটি পান এবং দেখুন যে আপেক্ষিক অবস্থানের পিক্সেলটি সাদা নয় (যার অর্থ সংঘর্ষ রয়েছে)।

কোড (পরীক্ষিত নয়):

bool IsMouseTouchingHexagon(Vector2 mousePosition, Vector2 hexagonPosition,
    Rectangle hexagonRectangle, Texture2D hexagonImage)
{
    Vector2 mousePositionToTopLeft = mousePosition - hexagonPosition;

    // We make sure that the mouse is over the hexagon's rectangle.
    if (mousePositionToTopLeft.X >= 0 && mousePositionToTopLeft.X < hexagonRectangle.Width && 
        mousePositionToTopLeft.Y >= 0 && mousePositionToTopLeft.Y < hexagonRectangle.Height)
    {
        // Where "PixelColorAt" returns the color of a pixel of an image at a certain position.
        if (PixelColorAt(hexagonImage, mousePositionToTopLeft) == Color.White)
        {
            // If the color is not white, we are colliding with the hexagon
            return true;
        }
    }

    // if we get here, it means that we did not find a collision.
    return false;
}

পুরো প্রক্রিয়াটির পারফরম্যান্স উন্নত করতে আপনি অবশ্যই স্পষ্টতই একটি আয়তক্ষেত্রের সংঘর্ষের চেক (আপনার সম্পূর্ণ ষড়জ্বল চিত্রের) করতে পারেন।

ধারণাটি বুঝতে এবং বাস্তবায়নের জন্য বেশ সহজ, তবে কেবলমাত্র যদি আপনার হেক্সাগনগুলি সমস্ত একই হয় তবে কাজ করে। এটি যদি আপনার কেবলমাত্র সম্ভাব্য ষড়ভুজ মাত্রাগুলির একটি সেট থাকে তবে এটি কাজ করতে পারে, যার অর্থ হবে আপনার একাধিক সংঘর্ষের ওভারলে দরকার হবে would

যদি এটি আরও অনেক সম্পূর্ণ এবং পুনরায় ব্যবহারযোগ্য হতে পারে (ম্যাথগুলি সত্যই সংঘর্ষের সন্ধান করতে ব্যবহার করে) হতে পারে তার খুব সরল সমাধান বলে মনে হয় তবে এটি অবশ্যই আমার মতে চেষ্টা করার মতো।


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

0

সেখানে একটি নিবন্ধ এর খেলা প্রোগ্রামিং রত্ন 7 নামক মৌমাছি এবং গেমাররা জন্য: ষড়্ভুজাকার টাইলস হ্যান্ডেল কিভাবে ঠিক আপনার যা প্রয়োজন হবে পারে।

দুর্ভাগ্যক্রমে আমার কাছে এই মুহুর্তে আমার কাছে বইটির অনুলিপিটি নেই, অন্যথায় আমি এটি একটু বর্ণনা করতে পারতাম।

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