Coordinate system for heptagonal tiling of hyperbolic plane
While playing HyperRogue (which is awesome, by the way), I began to wonder how such game could be implemented. Crucial component would be discrete coordinate system for hyperbolic tiling, and it turned out that it’s not entirely trivial.
Let’s take
heptagrid $\{7, 3\}$
.
Consider two fragments of this tiling: obtuse sector $0$ and acute sector $1$.
Obtuse sector can be partitioned into apex tile, two copies of obtuse sector, and one copy of acute sector. Acute sector partitions into apex tile, one copy of obtuse sector, and one copy of acute sector:
This partitioning rule can be written as $T^2$:
and it happens to coincide with the rabbit rule $T$ applied twice!
This also explains why “generations” of this partition form Fibonacci words:
$$ \begin{align} & S_0 = 0, \\ & S_2 = 010, \\ & S_4 = 01001010, \\ & ... \end{align} $$ | $$ \begin{align} & S_1 = 01, \\ & S_3 = 01001, \\ & ... \end{align} $$ |
Anyway, we now have a natural way to refer to heptagonal tiles:
data Heptagon = Heptagon RabbitHistory
deriving Eq
Since rabbit history can be imaginary, this data type is capable of representing any tile on a plane, not only those within a particular sector.
Operations:
origin :: Heptagon
origin = Heptagon (ImaginaryHistory 0)
adjacent :: Heptagon -> [Heptagon]
adjacent (Heptagon h) = map Heptagon (
let
grandparent = up (up h)
left_cousin = left h
right_cousin = right h
grandchildren = [h2 | h1 <- down h,
h2 <- down h1]
in
[grandparent] ++
[left_cousin] ++
grandchildren ++
[right_cousin]
)
Unfortunately, this implementation of adjacent
has a defect.
It will be addressed in
the follow-up post.