Home Game Development second – How do I rotate a construction of hexagonal tiles on a hexagonal grid?

second – How do I rotate a construction of hexagonal tiles on a hexagonal grid?

0
second – How do I rotate a construction of hexagonal tiles on a hexagonal grid?

[ad_1]

Let’s first outline a brand new quantity. No worries, it is a simple one.

Or, to place it merely: f = √3 × i, with i being the imaginary unit. With this, a rotation by 60 levels clockwise is similar as multiplication by 1/2 × (1 – f), and rotation by 60 levels counter-clockwise the identical as multiplication by 1/2 × (1 + f). If this sounds unusual, do not forget that multiplication by a fancy quantity is similar as rotation within the 2D aircraft. We simply “squash” the complicated numbers within the imaginary course a bit (by √3) to not should take care of sq. roots … or non-integers, for that matter.

We can even write the purpose (a,b) as a + b × f.

This lets us rotate any level within the aircraft; for instance, the purpose (2,0) = 2 + 0 × f rotates to (1,-1), then to (-1,-1), (-2,0), (-1,1), (1,1) and at last again to (2,0), just by multiplying it.

Of course, we want a approach to translate these factors from our coordinates to these we do the rotations in, after which again once more. For this, one other bit of data is required: If the purpose we do the rotation round is to the “left” or to the “proper” of the vertical line. For simplicity, we declare that’s has a “wobble” worth w of 0 if it is to the left of it (like the middle of the rotation [0,0] in your backside two photos), and of 1 if it is to the fitting of it. This extends our unique factors to be three-dimensional; (x, y, w), with “w” being both 0 or 1 after normalisation. The normalisation perform is:

NORM: (x, y, w) -> (x + flooring(w / 2), y, w mod 2), with the “mod” operation outlined such that it solely returns optimistic values or zero.

Our algorithm now appears as follows:

  1. Transform our factors (a, b, c) to their positions relative to the rotational centre (x, y, w) by calculating (ax, by, cw), then normalising the consequence. This places the rotational centre at (0,0,0) clearly.

  2. Transform our factors from their “native” coordinates to the rotational complicated ones: (a, b, c) -> (2 × a + c, b) = 2 × a + c + b × f

  3. Rotate our factors by multiplying them with one of many rotational numbers above, as wanted.

  4. Ra-transform the factors again from the rotational coordinates to their “native” ones: (r, s) -> (flooring(r / 2), s, r mod 2), with “mod” outlined as above.

  5. Re-transform the factors again to their unique place by including them to the rotational centre (x, y, z) and normalising.


A easy model of our “triplex” numbers based mostly f in C++ would appear like this:

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

class triplex {
    public:
        int r; /* actual half */
        int s; /* f-imaginary half */
        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 &different)
        {
            this->r = different.r; this->s = different.s;
        }
    non-public:
        /* C++ has loopy 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; easy sufficient
         */
        triplex & operator=(const triplex &rhs)
        {
            this->r = rhs.r; this->s = rhs.s;
            return *this;
        }
        /*
         * Multiplication operators - our fundamental 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 &different)
        {
            return triplex(*this) *= different;
        }
        /*
         * Now for the rotations ...
         */
        triplex rotate60CW() /* rotate this by 60 levels clockwise */
        {
            /*
             * The rotation is similar as multiplikation with (1,-1)
             * adopted by halving all values (multiplication by (1/2, 0).
             * If the values come from transformation from a hex subject,
             * they are going to at all times land again on the hex subject; else
             * we'd lose some data as a result of final 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 might prefer to get a hex again (truly, I'd
         * usually create this as a constructor of the hex class)
         */
        operator hex()
        {
            return hex(_div(this->r, 2), this->s, _mod(this->r, 2));
        }
};

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here