Assigning Tiles on a Hyperbolic Grid with Unique Coordinates

161 Views Asked by At

I am creating a location in an RPG campaign that deals with non-euclidean space, and I'm currently toying with the idea of a forest with a finite border that takes up infinite space.

The idea is that from the outside, the forest appears to be six trees arranged in a hexagon, but depending on which pair of trees you enter through, you find yourself in a different 'hexagon' of space. The way that space has been expanded inside the forest is based on the idea that the forest contains a hexagonal grid of trees, and you need to walk 720 degrees around a tree to end up where you started. Hence, while you enter a different space depending on which entrance you take, spinning 360 degrees around either of the trees at the entrance to that space will land you at one of the other entrances.

This pattern - with six hexagons surrounding a given point - can be represented slightly more intuitively on a hyperbolic plane using a tiling with six hexagons adjacent to each vertex. I've provided a labelled projection of such a plane on the Poincare disc to (hopefully) help illustrate my idea. While only five are visible on the diagram, it is clear that each entrance hex is repeated infinitely many times on this grid.

My goal is to find a coordinate system which I can use to uniquely label every hex in the forest so that I can easily identify if one hex is equivalent to another hex. Using the green hex on the diagram as a reference, notice how there's two separate paths someone could take to get there depending on which entrance they used? I want to have a way of labelling hexes which lets me say "Entering from here and going NE then SE will get you to the same place as entering from there and going S, NW, N, SW, SE.". It would also be nice to have some clear way of navigating a shortest path from hex A to hex B in this system, if possible.

If the non-euclidean nature of the grid is making this difficult to comprehend, imagine a very basic infinite square grid. I could label a repeating 8x8 section of that grid with the coordinates (0,0) through to (7,7), then apply a modulus to the coordinates whenever I moved so that instead of going from (7,7) to (8,7) I go to (0,7). Equally, to uniquely label every space on an infinite grid, I could represent every square as the movements it took to get there from some origin square (3 norths, 2 easts, and so on), and then whenever I moved I could simplify the expression to ensure that I never give the same square two different names (3 easts, 2 norths and 4 souths would be simplified to 2 souths, 3 easts).

Does such an approach to naming coordinates exist for such a non-euclidean space? Is there a way to unambiguously name each coordinate so that I can tell if two paths reach the same destination?

Obligatory disclaimer: I am aware how rapidly space expands in this sort of system, and I may end up handwaving navigation between landmarks and just let players travel between any two destinations they have directions for. This post is, at least partially, a matter of curiosity and problem solving, not just an attempt to make something for an RPG campaign easy to represent.

1

There are 1 best solutions below

0
On

I found a solution that involves modelling the overall structure like a tree with certain properties, then assigning coordinates based on the hierarchy of that tree. Notably, this coordinate system works for a significant number of other structures of this form. I will discuss the specifics of this generalisation later.

Solution

We will first describe all hexes who share a vertex with the outside of the structure as hexes in 'Ring 1'. Every other hex that shares a vertex with a hex in Ring 1 is in Ring 2, and so on. Note that every Ring forms a cycle of hexes - every hex is adjacent to exactly two hexes from its Ring.

We can now uniquely identify any given hex by its Ring's number and the hex's position within its Ring. To describe its position within the Ring, we will identify its lineage of parents in previous Rings. Unfortunately, since not every hex is connected to a hex in the previous Ring, we will choose an arbitrary direction like counter-clockwise, and say that parent-less hexes are considered to have the parent that the nearest non-parent-less hex has. Now that every hex can have its ancestry uniquely traced, it can be uniquely identified.

We will denote the most counter-clockwise child of a hex as the child with 'index 0' (numbering the remaining children with consecutive integers, clockwise), and the total number of children belonging to a single parent as that group of children's 'limit' (for consistency, this will also be 'zero-indexed', so a limit of 2 means there are 3 unique indexes in this group). We will use the notation / to indicate a hex's position within its parent's set of children.

We may also note that every hex has either 2 or 3 connections to hexes within its Ring or in the previous Ring. Because every hex is connected to 6 hexes, this means they each connect to a further 4 or 3 hexes on the next Ring. Additionally, in between every hex connected to the previous Ring will be 2 or 3 hexes which exist to enforce the fact that every vertex is surrounded by six hexes. We can actually tell how many children a hex will have based on its index (in this case the limit is irrelevant), specifically any hex with an index divisible by 4 will connect to 3 hexes on the next Ring (and have 8 other children, totalling 11), and other hexes will connect to 4 hexes (and have 11 other children, totalling 15). This will be useful later.

To deal with some base cases we will say the limit of the outside of the structure is 5 (representing the six entrances) and the limit of each group of children on the outermost Ring is 2. So the hexes you enter once you've walked into the forest would be notated 0/5 - 0/2, 1/5 - 0/2, 2/5 - 0/2, and so on.

Finally, to navigate from one hex to another:

  • When moving into a deeper Ring - Label the paths from your hex to hexes in the next Ring clockwise with the numbers 0 through 3 or 0 through 2 as appropriate. Multiply this number by 4, this is the new index. Figure out the limit of this hex (11 or 15, as stated earlier), then add these new components to the end of your current coordinates.
  • When moving into an outer Ring - Remove the last component of the coordinate (note that this movement is only possible when your current index is divisible by 4).
  • When moving across a Ring - Add 1 to the index of your Ring. If that makes it larger than the limit, increase your parent's index, recalculate your limit and set your index to '0'. If your parent's index is now greater than its limit, repeat this process (and so on for its parent, and its parent, until you reach the outside).

Examples

You start by entering 0/5 - 0/2. By continually moving clockwise across this outermost Ring, you move to 0/5 - 1/2, 0/5 - 2/2, 1/5 - 0/2, 1/5 - 1/2 and so on until you get back to 0/5 - 0/2. This is demonstrates the required property of ending up at a new entrance if you swing 360 degrees around one of the outermost trees upon entering.

You start by entering 0/5 - 0/2. From here you can go into the next Ring through 0/5 - 0/2 - 0/10, 0/5 - 0/2 - 4/10 and 0/5 - 0/2 - 8/10.

You're at 3/5 - 2/2 - 14/14 - 13/14. You move clockwise across your Ring, bringing you to 3/5 - 2/2 - 14/14 - 14/14. You move clockwise again, bringing you to 4/5 - 0/2 - 0/10 - 0/10.

Conclusion and Generalisability

We now have a coordinate system which uniquely identifies each hex in the forest, and a means by which to navigate between them.

That said, could a similar technique be used for other impossible geometries? Yes! While deciding what the entrance(s) to your very own non-euclidean forest may look like, you can replicate this coordinate system for any non-euclidean space which can be modelled as a tree (or repetition thereof), so long as all necessary details about a child can be identified by its parents. It will be easiest to do this if every space in the forest has the same number of sides and every tree the same number of vertices connecting to it, but this is far from mandatory.

For example, why not make an identical forest on a square grid? 8 squares around one tree, each square connects to 4 other squares. Or what about a hexagonal forest with 5 hexes around each tree instead of 6? If you make the number of spaces connected a single tree infinite, you could make a tree that you could keep running around forever without getting back to where you started (at this point, you can stop keeping track of limits - every child connected to its parent has an infinite number of spaces on its Ring between it and the next connected sibling, and at that point you may as well start using negative indexes as well as positive ones).

Hope this was helpful to anyone who ends up with the same very specific problem to solve as I!