मैं हेक्सागोनल ग्रिड पर हेक्सागोनल टाइल्स की संरचना को कैसे घुमाऊं?


10

मेरा 2 डी आइसोमेट्रिक गेम एक हेक्सागोनल ग्रिड मैप का उपयोग करता है। नीचे दी गई छवि के संदर्भ में, मैं गुलाबी हेक्सागोन्स के चारों ओर 60 डिग्री तक हल्के नीले हेक्सागोन संरचनाओं को कैसे घुमाऊं?

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

संपादित करें:

मुख्य हेक्स (0,0) है। अन्य हेक्स बच्चे हैं, उनमें से गिनती तय है। मैं केवल एक स्थिति को परिभाषित करने जा रहा हूं (इस मामले में इसके दाएं) और यदि आवश्यक हो तो अन्य दिशाओं की गणना करें (बाएं-नीचे, दाएं-बॉटम, दाएं-शीर्ष, बाएं-शीर्ष और बाएं)। अन्य हेक्स को इस प्रकार परिभाषित किया गया है: Package.Add (-1,0), Package.Add (-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
वास्तव में समस्या क्या है? कैसे लागू करने के लिए कि या कुछ बुरा परिणाम?
अली

क्या आप गुलाबी षट्भुज के 6 किनारों पर घुमावों को तड़क रहे हैं, या रोटेशन के कोण मनमाने हैं? इसके अलावा, दाईं ओर की संरचना में गुलाबी हेक्सागोन्स में से आप किसके चारों ओर घूम रहे हैं?
कीबलब्रॉक्स

व्यक्तिगत टाइलों को घुमाना आसान हो सकता है, लेकिन इससे सवाल उठता है कि जो टाइलें पहले से हैं, उनका क्या होगा और इससे पहले कि मैं कोशिश करूं और प्रतिक्रिया दे सकूं, सामान्य रूप से जानना अच्छा होगा।
जेम्स

गलती के लिए क्षमा करें। मैं छवि के बाएं हिस्से के बारे में बात कर रहा हूं। मेरे पास बुरे परिणाम थे, कभी-कभी कुछ हेक्स गलत स्थानों पर होते हैं। गुलाबी हेक्स मुख्य है और चमकदार नीली हेक्स चिल्ड हैं। मान लीजिए कि मुख्य हेक्स (5,5) है, तो मैं एक बच्चे को हेक्स (-1,0) परिभाषित करता हूं, इसलिए बच्चा गुलाबी के बाईं ओर है और इसी तरह। मैं जानना चाहता हूं कि इस बच्चे को 60 डिग्री तक कैसे घुमाया जाए (तब यह गुलाबी रंग के बाईं ओर होगा)। आसान: मैं अपनी रणनीति के खेल में निर्माण प्रणाली पर काम कर रहा हूँ। अक्सर रणनीति के खेल में आप इसे रखने से पहले इमारत को घुमा सकते हैं। मैं उन हेक्स की गणना करने जा रहा हूं जिन्हें बनाने की आवश्यकता है।
रुजोसो

क्या चयनित हेक्स के सेट को हर बार समान रूप से गिनना पड़ता है? यही है, क्या आप उदाहरण के लिए विशेष रूप से गुलाबी हेक्स के दोनों ओर 3 वस्तुओं को हेक्स पर रख रहे हैं? या क्या आप किसी दी गई लंबाई की एक रेखा खींचना चाहते हैं और यह तय करना चाहते हैं कि कौन सा हेक्स सबसे अच्छा है, चाहे वह कितना भी हो? क्या आप हेक्स की एक निश्चित संख्या, या एक मनमानी संख्या के साथ ऐसा करना चाहते हैं?
टिम होलट

जवाबों:


11

जैसा मार्टिन Sojka नोट, रोटेशन सरल करता है, तो आप एक अलग करने के लिए कनवर्ट समन्वय प्रणाली, रोटेशन प्रदर्शन कर रहे हैं, फिर वापस परिवर्तित।

मैं मार्टिन के लेबल की तुलना में एक अलग समन्वय प्रणाली का उपयोग करता हूं x,y,z। इस प्रणाली में कोई लड़खड़ाहट नहीं है, और यह बहुत सारे हेक्स एल्गोरिदम के लिए उपयोगी है। इस प्रणाली में आप हेक्स को चारों ओर 0,0,0घुमाकर निर्देशांक को " घुमा " सकते हैं और उनके संकेतों को फ़्लिप कर सकते हैं: एक तरह से और दूसरे तरीके से x,y,zबदल जाता है । इस पृष्ठ पर मेरा एक चित्र है ।-y,-z,-x-z,-x,-y

(मैं x / y / z बनाम X / Y के बारे में क्षमा चाहता हूं, लेकिन मैं अपनी साइट पर x / y / 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 ° दाईं ओर घुमाएं :

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

जैसा कि आप यहाँ देख रहे हैं:

हेक्स रोटेशन उदाहरण -2,1,1 के लिए

फिर -1,2,-1वापस कन्वर्ट करें :

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

तो (X = -2, Y = 1) 60 ° दाएं घूमता है (X = -2, Y = -1)।


4

आइए सबसे पहले एक नई संख्या को परिभाषित करें। कोई चिंता नहीं, यह एक आसान है।

  • f : f × f = -3

या, इसे सीधे शब्दों में कहें: f = simply3 × i , मैं काल्पनिक इकाई होने के साथ । इसके साथ, 60 डिग्री दक्षिणावर्त द्वारा एक घुमाव 1/2 × (1 - f ) से गुणा के समान है , और 60 डिग्री काउंटर-क्लॉकवाइज द्वारा रोटेशन 1/2 × (1 + f ) से गुणा के समान है। । यदि यह अजीब लगता है, तो याद रखें कि एक जटिल संख्या से गुणा 2 डी विमान में रोटेशन के समान है। हम काल्पनिक दिशा में थोड़े से (inary3 द्वारा) जटिल संख्याओं को "स्क्वैश" करते हैं, ताकि उस मामले के लिए वर्गमूल ... या गैर-पूर्णांक से न निपटें।

हम बिंदु (ए, बी) को + बी × एफ के रूप में भी लिख सकते हैं ।

इससे हम विमान के किसी भी बिंदु को घुमा सकते हैं; उदाहरण के लिए, बिंदु (2,0) = 2 + 0 × f घूमता है (1, -1), फिर (-1, -1), (-2,0), (-1,1), ( 1,1) और अंत में (2,0) तक, बस इसे गुणा करके।

बेशक, हमें अपने निर्देशांक से उन बिंदुओं का अनुवाद करने का एक तरीका चाहिए जो हम घुमावों को करते हैं और फिर वापस करते हैं। इसके लिए, एक और जानकारी की आवश्यकता है: यदि हम जिस बिंदु के चारों ओर घुमाव करते हैं वह ऊर्ध्वाधर रेखा के "दाएं" या "दाएं" है। सादगी के लिए, हम यह घोषित करते हैं कि 0 का "डगमगाने" मान w है यदि यह इसके बाईं ओर है (जैसे कि रोटेशन का केंद्र [0,0] आपके निचले दो चित्रों में), और 1 यदि यह दाईं ओर है तो इसका। यह हमारे मूल बिंदुओं को तीन आयामी बनाता है; ( x , y , w ), "w" सामान्य होने के बाद या तो 0 या 1 है। सामान्यीकरण समारोह है:

NORM: ( x , y , w ) -> ( x + फ्लोर ( w / 2), y , w mod 2), "मॉड" ऑपरेशन के साथ परिभाषित किया गया है कि यह केवल सकारात्मक मान या शून्य देता है।

हमारा एल्गोरिथ्म अब इस प्रकार दिखता है:

  1. हमारे अंक (रूपांतरण एक , , घूर्णी केंद्र (के सापेक्ष अपनी स्थिति के लिए) एक्स , वाई , w (गणना के द्वारा) एक - एक्स , द्वारा , - डब्ल्यू ), तो परिणाम सामान्य। यह स्पष्ट रूप से घूर्णी केंद्र (0,0,0) डालता है।

  2. हमारे बिंदुओं को उनके "मूल" से बदलकर घूर्णी जटिल वाले से समन्वयित करें: ( , बी , सी ) -> (2 × a + c , b ) = 2 × a + c + b × f

  3. आवश्यकतानुसार हमारे घूर्णन संख्याओं में से एक के साथ गुणा करके हमारे बिंदुओं को घुमाएं।

  4. घूर्णन से वापस बिंदुओं को अपने "मूल" वाले: ( r , s ) -> (मंजिल ( r / 2), s , r mod 2) से बदलकर, "mod" को उपरोक्त के रूप में परिभाषित किया गया है।

  5. बिंदुओं को घूर्णी केंद्र ( x , y , z ) से जोड़कर और उन्हें सामान्य करके उनकी मूल स्थिति में पुनः रूपांतरित करें ।


आधार पर हमारे "triplex" संख्या का एक सरल संस्करण 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));
        }
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.