1
$\begingroup$

Consider the following piecewise surjective function:

$$ f(x) = \begin{cases} x + 19 & x < 0 \\ x & x \geq 0 \end{cases} $$

We have the following restriction on the domain:

  • $x \in \{ -16,-15,-14,-9,-8,-7,-6,-2,-1,0,1,2,6,7,8,9,14,15,16 \}$

Hence, the codomain has the following values:

  • $f(x) \in \{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 \}$

Naively, we can define the inverse as follows:

$$ g(y) = \begin{cases} y - 19 & y \in \{ 3,4,5,10,11,12,13,17,18 \} \\ y & y \in \{ 0,1,2,6,7,8,9,14,15,16 \} \end{cases} $$

Is there a better way to determine which set $y$ is an element of? Unfortunately, the two sets are non-contiguous and the contiguous subsets are of variable sizes. Otherwise, my first instinct was to use modular arithmetic to define a closed-form expression. I'm interested in a general solution because I have a whole family of such functions that I need to find the inverse of.


To explain how I defined the domain, consider the following vectorization of a hexagonal map:

        16
    15      09
14      08      02
    07      01
06      00      13
    18      12
17      11      05
    10      04
        03

I've already explained what this means at length in this linked answer. The general idea is to convert a two-dimensional hexagonal map into a one-dimensional array. The numbering in the above diagram denotes the ordering of hexagonal cells in the one-dimensional array. It's arranged in a way that enables neighbors of any given cell (including neighbors that wraparound the edges of the map) to be computed easily using modular arithmetic.

Now, I'd like to create a bijection between the above indices and the following axial coordinates:

                    +0,+2
          -1,+2               +1,+1
-2,+2               +0,+1               +2,+0
          -1,+1               +1,+0
-2,+1               +0,+0               +2,-1
          -1,+0               +1,-1
-2,+0               +0,-1               +2,-2
          -1,-1               +1,-2
                    +0,-2

We can convert the axial coordinates into numbers that are congruent to the corresponding indices $\bmod{19}$ (the total number of cells in the hexagonal map) using the following function:

$$ fromAxial(x, y) = x + 8y $$

This converts the axial coordinates into the following values (which is how we get our domain). Notice that only the values at the bottom are negative and that they mirror the values on the top:

            +16
      +15         +09
+14         +08         +02
      +07         +01
+06         +00         -06
      -01         -07
-02         -08         -14
      -09         -15
            -16

We can convert these values back into axial coordinates using the following functions:

$$ \begin{align} toAxialX(v) &= ((v + 2) \bmod 8) - 2 \\ toAxialY(v) &= \lfloor (v + 2) \div 8 \rfloor \end{align} $$

Now, to convert axial coordinates to the corresponding indices we use $f \circ fromAxial$ where $f$ is the function I defined in the beginning. Equivalently, we could write $fromAxial(x, y) \bmod 19$.

Similarly, to convert indices back to axial coordinates we use $toAxialX \circ g$ and $toAxialY \circ g$ respectively where $g$ is the inverse of $f$. Note that these functions are currently defined for a hexagonal map of side length $3$. For different sized hexagonal maps we'd use similar functions with only certain values changing. Hence, I'm looking for a general solution to define the inverse of $f$.

$\endgroup$
  • 1
    $\begingroup$ Was the domain chosen at random? (Subject to forming a bijection of course.) If so, there is unlikely to be any simple general answer to your question. If there was a reason for choosing this particular domain, maybe you could give details, then you would have a better chance of getting a useful answer. $\endgroup$ – David Sep 11 '18 at 4:15
  • $\begingroup$ @David No, the domain was not chosen at random. I edited my answer and added details. However, I'm not sure whether it'll be useful towards answering my question. Still, I hope that it does elucidate it. $\endgroup$ – Aadit M Shah Sep 11 '18 at 5:49
0
$\begingroup$

The simplest way to solve this problem is by converting to cube coordinates instead of axial coordinates:

                                +0,+2,-2
                -1,+2,-1                        +1,+1,-2
-2,+2,+0                        +0,+1,-1                        +2,+0,-2
                -1,+1,+0                        +1,+0,-1
-2,+1,+1                        +0,+0,+0                        +2,-1,-1
                -1,+0,+1                        +1,-1,+0
-2,+0,+2                        +0,-1,+1                        +2,-2,+0
                -1,-1,+2                        +1,-2,+1
                                +0,-2,+2

Cube coordinates are the same as axial coordinates, except that they have a z-coordinate whose values are the negated sum of the other two coordinates (i.e. $z = -x - y$). This allows us to detect invalid coordinates easily because they will be off the map. We can use the following distance formula to test for them:

$$ distance(x, y, z) = \frac{\lvert x \rvert + \lvert y \rvert + \lvert z \rvert}{2} $$

Converting cube coordinates to indices is the same as converting axial coordinates to indices:

$$ fromCube(x, y, z) = (x + 8y) \bmod 19 $$

Converting indices back to cube coordinates is also the same:

$$ \begin{align*} toCube(i) &= (x, y, z) \\ \text{where}~x &= ((i + 2) \bmod 8) - 2 \\ y &= (i - x) \div 8 \\ z &= -x - y \end{align*} $$

However, we now include a distance check to ensure that indices are converted to the correct coordinates:

$$ fromIndex(i) = \begin{cases} toCube(i - 19) & distance(toCube(i)) > 2 \\ toCube(i) & distance(toCube(i)) \leq 2 \end{cases} $$

This can be generalized to hexagonal maps of different sizes by simply changing certain values.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.