ষড়ভুজীয় গ্রিডে আমি কীভাবে ষড়ভুজ টাইলসের কাঠামোটি ঘোরান?


10

আমার 2 ডি আইসোমেট্রিক গেমটি হেক্সাগোনাল গ্রিড মানচিত্র ব্যবহার করে। নীচের চিত্রের রেফারেন্সে, আমি কীভাবে গোলাপী ষড়জাগুলির চারদিকে 60 ডিগ্রি দ্বারা হালকা নীল ষড়ভুজ কাঠামো ঘোরান?

http://www.algonet.se/~afb/spriteworld/ongoing/HexMap.jpg

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

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

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

switch(Direction)
{
case DirRightDown:
    if(Number.Y % 2 && Point.X % 2)
        Number.X += 1;
    Number.Y += Point.X + Point.Y / 2;

    Number.X += Point.X / 2 - Point.Y / 1.5;
    break;
}

এই Numberকোডটিতে প্রধান হেক্স এবং Pointহেক্সটি আমি ঘুরতে চাই, তবে এটি কার্যকর হয় না:

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


1
ঠিক সমস্যা কি? কিভাবে বা কিছু খারাপ ফলাফল বাস্তবায়ন?
Ali1S232

আপনি কি গোলাপী ষড়্ভুজের 6 টি প্রান্তে ঘোরাফেরা করছেন, বা ঘোরানো কোণগুলি নির্বিচারে? এছাড়াও, ডান পাশের কাঠামোর কোনও গোলাপী হেক্সাগনটি আপনি চারদিকে ঘুরছেন?
কেবেলব্রক্স

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

ভুলের জন্য দুঃখিত. আমি ছবির বাম অংশ সম্পর্কে কথা বলছি। আমার খারাপ ফলাফল হয়েছিল, কখনও কখনও কয়েকটি হেক্সস ভুল জায়গায় থাকে। গোলাপী হেক্স্স প্রধান এবং উজ্জ্বল নীল হেক্সস হ'ল চাইল্ড। ধরা যাক মূল হেক্স (5,5) হয় তবে আমি একটি চাইল্ড হেক্স (-1,0) সংজ্ঞায়িত করি তাই শিশুটি গোলাপী রঙের বাম দিকে থাকে এবং আরও অনেক কিছু। আমি জানতে চাই যে এই শিশু হেক্সকে 60 ডিগ্রি দ্বারা কীভাবে ঘোরানো হবে (তারপরে এটি গোলাপীর বাম-শীর্ষে থাকবে)। সহজ: আমি আমার কৌশল গেমটিতে বিল্ড সিস্টেমের কাজ করছি। প্রায়শই কৌশলগত গেমগুলিতে আপনি বিল্ডিং স্থাপনের আগে বিল্ডিং ঘোরান। আমি যে hexes তৈরি করতে হবে তা গণনা করতে যাচ্ছি।
ruzsoo

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

উত্তর:


11

মার্টিন সোজকা নোট হিসাবে , আবর্তনগুলি সহজ হয় যদি আপনি কোনও ভিন্ন সমন্বয় ব্যবস্থাতে রূপান্তর করেন, ঘূর্ণন সঞ্চালন করেন, তবে ফিরে রূপান্তর করুন।

আমি মার্টিনের চেয়ে আলাদা একটি সমন্বিত সিস্টেম ব্যবহার করি, লেবেলযুক্ত x,y,z। এই সিস্টেমে কোনও ঝাঁকুনি নেই, এবং এটি প্রচুর হেক্স অ্যালগোরিদমের জন্য দরকারী। এই সিস্টেমে আপনার চারপাশের হেক্স ঘুরান পারেন 0,0,0: "আবর্তিত" স্থানাঙ্ক এবং তাদের লক্ষণ আলোকসম্পাতের দ্বারা x,y,zমধ্যে সক্রিয় -y,-z,-xওয়ান ওয়ে এবং -z,-x,-yঅন্যান্য উপায়। আমার এই পৃষ্ঠায় একটি চিত্র রয়েছে ।

(আমি এক্স / ওয়াই / জেড বনাম এক্স / ওয়াই সম্পর্কে দুঃখিত তবে আমি আমার সাইটে এক্স / ওয়াই / জেড ব্যবহার করি এবং আপনি আপনার কোডে এক্স / ওয়াই ব্যবহার করেন তাই এই উত্তরটির ক্ষেত্রে বিষয়টি গুরুত্বপূর্ণ! সুতরাং আমি ব্যবহার করতে যাচ্ছি xx,yy,zzপার্থক্যটি আরও সহজ করার চেষ্টা করার জন্য নীচের পরিবর্তনশীল নাম হিসাবে।)

আপনার রূপান্তর করুন X,Yস্থানাঙ্ক থেকে x,y,zবিন্যাস:

xx = X - (Y - Y&1) / 2
zz = Y
yy = -xx - zz

60 ° এক উপায় বা অন্য দ্বারা একটি ঘূর্ণন সম্পাদন করুন:

xx, yy, zz = -zz, -xx, -yy
     # OR
xx, yy, zz = -yy, -zz, -xx

x,y,zআপনার পিছনে রূপান্তর করুন X,Y:

X = xx + (zz - zz&1) / 2
Y = zz

উদাহরণস্বরূপ, আপনি যদি (X = -2, Y = 1) দিয়ে শুরু করেন এবং 60 ° ডানদিকে ঘোরানো চান, আপনি রূপান্তর করতে চান:

xx = -2 - (1 - 1&1) / 2 = -2
zz = 1
yy = 2-1 = 1

তারপরে -2,1,160 rot ডানদিকে ঘোরান :

xx, yy, zz = -zz, -xx, -yy = -1, 2, -1

যেমন আপনি এখানে দেখুন:

-2,1,1 এর জন্য হেক্স রোটেশন উদাহরণ

তারপরে -1,2,-1ফিরে রূপান্তর করুন :

X = -1 + (-1 - -1&1) / 2 = -2
Y = -1

সুতরাং (এক্স = -2, ওয়াই = 1) 60 ° ডানদিকে ঘুরান (এক্স = -2, ওয়াই = -1)।


4

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

  • f : f × f = -3

বা এটিকে সহজভাবে বলতে গেলে : f = √3 × i , আমি কাল্পনিক একক হিসাবে । এটির সাথে, 60 ডিগ্রি ঘড়ির কাঁটার দিক দিয়ে ঘোরানো 1/2 × (1 - f ) দ্বারা গুনের সমান এবং 60 ডিগ্রি ঘড়ির কাঁটার বিপরীতে 1/2 × (1 + f ) দ্বারা গুণণের সমান । যদি এটি অদ্ভুত মনে হয় তবে মনে রাখবেন যে একটি জটিল সংখ্যার দ্বারা গুণ 2 ডি প্লেনে ঘোরার মতো। আমরা কেবল এই বিষয়টির জন্য বর্গমূল ... বা অ-পূর্ণসংখ্যার সাথে ডিল করতে না পারার জন্য কাল্পনিক দিকের জটিল সংখ্যাগুলি কেবল "স্কোয়াশ" করি।

আমরা বিন্দুটি (a, b) ++ b × f হিসাবেও লিখতে পারি ।

এটি আমাদের বিমানের যে কোনও পয়েন্টকে ঘোরানোর সুযোগ দেয়; উদাহরণস্বরূপ, বিন্দু (2,0) = 2 + 0 × f (1, -1) এ ঘোরা হয়, তারপরে (-1, -1), (-2,0), (-1,1), ( 1,1) এবং অবশেষে (২,০) এ ফিরে আসুন, কেবল এটি গুণ করে।

অবশ্যই, আমাদের পয়েন্টগুলিকে আমাদের স্থানাঙ্কগুলি থেকে আমরা যে আবর্তনগুলি করি সেগুলিতে অনুবাদ করার একটি উপায় প্রয়োজন এবং তারপরে আবার ফিরে আসা উচিত। এর জন্য আরও একটি বিট তথ্য প্রয়োজন: আমরা যে পয়েন্টটি চারদিকে ঘোরাই তা যদি হয় তবে "বাম" বা উল্লম্ব লাইনের "ডান" দিকে। সরলতার জন্য, আমরা ঘোষণা করছি যে একটি "টলিতে টলিতে চলা" মান রয়েছে W যদি এটা বাম (আপনার নীচে দুটি ছবির মধ্যে ঘূর্ণন [0,0] কেন্দ্রে মত) এর 0, এবং 1 এর, যদি তা সঠিক করার এটা। এটি আমাদের মূল পয়েন্টগুলি ত্রিমাত্রিক হতে প্রসারিত করে; ( x , y , w ), "ডাব্লু" স্বাভাবিকের পরে 0 বা 1 হয়। স্বাভাবিককরণের কাজটি হ'ল:

সাধারণ: ( x , y , ডাব্লু ) -> ( x + তল ( ডাব্লু / 2), ওয়াই , ডাব্লু মোড 2) "মোড" অপারেশনটিকে এমন সংজ্ঞায়িত করা হয়েছে যে এটি কেবল ধনাত্মক মান বা শূন্যকে ফিরিয়ে দেয়।

আমাদের অ্যালগরিদম এখন নীচের মত দেখাচ্ছে:

  1. আমাদের পয়েন্টগুলি ( , , সি ) ঘূর্ণন কেন্দ্রের তুলনায় তাদের অবস্থানগুলিতে ( x , y , w ) রূপান্তর করুন ( a - x , b - y , c - w ), তারপরে ফলাফলকে স্বাভাবিক করুন normal এটি স্পষ্টতই (0,0,0) এ ঘূর্ণন কেন্দ্র রাখে।

  2. আমাদের পয়েন্টগুলি তাদের "নেটিভ" স্থানাঙ্ক থেকে আবর্তনীয় জটিলগুলিতে রূপান্তর করুন: ( a , b , c ) -> (2 × a + c , b ) = 2 × a + c + b × f

  3. আমাদের পয়েন্টগুলি প্রয়োজনীয় হিসাবে উপরের ঘূর্ণন সংখ্যার সাথে গুণ করে তাদের ঘোরান।

  4. উপরের মত সংজ্ঞায়িত "মোড" সহ ঘূর্ণন স্থানাঙ্ক থেকে পয়েন্টগুলি তাদের "নেটিভ" হিসাবে ফিরিয়ে আনুন: ( আর , এস ) -> (তল ( আর / 2), এস , আর মোড 2)

  5. ঘূর্ণন কেন্দ্র ( x , y , z ) এ যোগ করে এবং স্বাভাবিক করে পয়েন্টগুলিকে তাদের মূল অবস্থানে ফিরিয়ে আনুন ।


ভিত্তি আমাদের "ত্রৈধ" সংখ্যার একটি সহজ সংস্করণ C ++ ভালো দেখাবে:

class hex {
    public:
        int x;
        int y;
        int w; /* "wobble"; for any given map, y+w is either odd or
                  even for ALL hexes of that map */
    hex(int x, int y, int w) : x(x), y(y), w(w) {}
    /* rest of the implementation */
};

class triplex {
    public:
        int r; /* real part */
        int s; /* f-imaginary part */
        triplex(int new_r, int new_s) : r(new_r), s(new_s) {}
        triplex(const hex &hexfield)
        {
            r = hexfield.x * 2 + hexfield.w;
            s = hexfield.y;
        }
        triplex(const triplex &other)
        {
            this->r = other.r; this->s = other.s;
        }
    private:
        /* C++ has crazy integer division and mod semantics. */
        int _div(int a, unsigned int b)
        {
            int res = a / b;
            if( a < 0 && a % b != 0 ) { res -= 1; }
            return res;
        }
        int _mod(int a, unsigned int b)
        {
            int res = a % b;
            if( res < 0 ) { res += a; }
            return res;
        }
    public:
        /*
         * Self-assignment operator; simple enough
         */
        triplex & operator=(const triplex &rhs)
        {
            this->r = rhs.r; this->s = rhs.s;
            return *this;
        }
        /*
         * Multiplication operators - our main workhorse
         * Watch out for overflows
         */
        triplex & operator*=(const triplex &rhs)
        {
            /*
             * (this->r + this->s * f) * (rhs.r + rhs.s * f)
             * = this->r * rhs.r + (this->r * rhs.s + this->s * rhs.r ) * f
             *   + this->s * rhs.s * f * f
             *
             * ... remembering that f * f = -3 ...
             *
             * = (this->r * rhs.r - 3 * this->s * rhs.s)
             *   + (this->r * rhs.s + this->s * rhs.r) * f
             */
            int new_r = this->r * rhs.r - 3 * this->s * rhs.s;
            int new_s = this->r * rhs.s + this->s * rhs.r;
            this->r = new_r; this->s = new_s;
            return *this;
        }
        const triplex operator*(const triplex &other)
        {
            return triplex(*this) *= other;
        }
        /*
         * Now for the rotations ...
         */
        triplex rotate60CW() /* rotate this by 60 degrees clockwise */
        {
            /*
             * The rotation is the same as multiplikation with (1,-1)
             * followed by halving all values (multiplication by (1/2, 0).
             * If the values come from transformation from a hex field,
             * they will always land back on the hex field; else
             * we might lose some information due to the last step.
             */
            (*this) *= triplex(1, -1);
            this->r /= 2;
            this->s /= 2;
        }
        triplex rotate60CCW() /* Same, counter-clockwise */
        {
            (*this) *= triplex(1, 1);
            this->r /= 2;
            this->s /= 2;
        }
        /*
         * Finally, we'd like to get a hex back (actually, I'd
         * typically create this as a constructor of the hex class)
         */
        operator hex()
        {
            return hex(_div(this->r, 2), this->s, _mod(this->r, 2));
        }
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.