Regular Polygons in the Poincare Disk

A hyperbolic polygon inside the disk is a set of points outside it, and for a regular one that set is a regular polygon.

We want to draw tilings of the hyperbolic plane by Coxeter polygons - the sort of picture where you hand a computer a list of walls and every pixel folds itself back into a fundamental domain. To do that we need to write a polygon down: not know that one exists, but produce the actual numbers.

So we have to choose a model, and we choose the Poincare disk. Partly because it is the one that makes the beautiful pictures. But mostly because of what a polygon looks like there: the sides are geodesic segments, and geodesics in the disk are arcs of Euclidean circles meeting the boundary at right angles. A hyperbolic polygon is a handful of ordinary circles in the plane, and circles are something we already know how to write down.

We also restrict to regular polygons, because the disk model is very happy about central symmetry - happy enough that the whole problem collapses to a single number.

Describing Geodesics by Points

Before the polygons, the sides. We want coordinates on the set of all geodesics of H2\HH^2, so let us first ask what that set is.

A geodesic is determined by where its two ends land on the circle at infinity, and there is no first end and no second end. So the space of geodesics is the space of unordered pairs of distinct points on a circle. Such a pair spans a chord, and a chord is the part inside the disk of an ordinary Euclidean line - so equivalently, and this is the version to hold onto, it is the space of lines in the plane which meet the open unit disk.

Lines are easy to coordinatize. Every line in the plane is

xn^=tx\cdot \hat n = t

for a unit normal n^S1\hat n\in S^1 and a signed distance tRt\in\RR, and the only redundancy is that (n^,t)(\hat n,t) and (n^,t)(-\hat n,-t) name the same line. So the space of lines is the cylinder S1×RS^1\times\RR modulo an involution which is antipodal on the circle and a reflection on the R\RR. That involution has no fixed points, and the quotient is an open Mobius band - cut the cylinder along a vertical line to get a strip, and the two ends are glued back with a flip.

A line meets the open disk exactly when t<1|t|<1, so the space of geodesics of the hyperbolic plane is that same band with R\RR narrowed to (1,1)(-1,1).

Now for the coordinates. The pair (n^,t)(\hat n,t) is not quite one, since it is only defined up to sign. But as long as t0t\neq0 we can divide the ambiguity away:

c=n^tc=\frac{\hat n}{t}

is unchanged by (n^,t)(n^,t)(\hat n,t)\mapsto(-\hat n,-t), and c=1/t>1\|c\|=1/|t|>1. So every geodesic except those with t=0t=0 is named by a single honest point cc outside the unit disk. The lines with t=0t=0 are the ones through the centre, and we will come back to them.

That point has a beautiful description in each of our two models.

In the Klein model geodesics are exactly the chords, so the line is the picture. Given cc outside the disk, draw the two tangent lines from cc to the boundary circle; the chord joining the two points of tangency is xc=1x\cdot c=1, which is our line. Every chord arises exactly once.

In the Poincare disk geodesics are arcs of circles meeting the boundary at right angles. Two circles of radii r1,r2r_1,r_2 whose centres are a distance dd apart are orthogonal when r12+r22=d2r_1^2+r_2^2=d^2, by the Pythagorean theorem, so against the unit circle a circle of centre cc and radius rr is a geodesic exactly when

r2+1=c2r^2+1=\|c\|^2

The radius is not a second piece of data: r=c21r=\sqrt{\|c\|^2-1}, which is the length of the tangent from cc to the unit circle. Swinging that tangent segment around cc sweeps out precisely the circle we want.

And it is the same cc. The orthogonal circle centred at cc meets the boundary where x=1\|x\|=1 and xc2=c21\|x-c\|^2=\|c\|^2-1, and expanding that second equation gives xc=1x\cdot c=1 - the same two points the tangents touched. So the Klein chord and the Poincare arc assigned to cc are one geodesic drawn in two models, and the tangent lines doing the work in Klein are the same tangent lines whose length is the radius in Poincare.

TheoremGeodesics and Exterior Points

Geodesics of the hyperbolic plane not passing through the centre correspond exactly to points cc with c>1\|c\|>1. In the Klein model the geodesic is the chord xc=1x\cdot c=1; in the Poincare disk it is the arc, inside the disk, of the circle centred at cc with radius the tangent length c21\sqrt{\|c\|^2-1}.

That leaves the geodesics with t=0t=0, which are the diameters. As a geodesic straightens towards one, cc runs off to infinity, and it does so in a definite direction: writing c=Ru^c=R\hat u, the circle is xu^=(x2+1)/2Rx\cdot\hat u=(\|x\|^2+1)/2R, which as RR\to\infty becomes the diameter perpendicular to u^\hat u. Opposite directions give the same diameter, so to finish the parameterization we glue on one point for each direction u^\hat u, with u^u^\hat u\sim-\hat u.

That glued-on circle is the core circle of the band, and everything checks out: a Mobius band minus its core circle is an annulus, and the exterior of the unit disk is an annulus.

Notice that this is not the compactification our model already came with. The Poincare disk lives in the Riemann sphere CP1\CP^1, and so do our exterior points - and out there the outside of the unit disk is not an annulus at all. It is another disk, closed up by the single point \infty. Had we taken the ambient space at its word we would have added that one point, and every diameter would have become the same geodesic.

So parameterizing geodesics means compactifying the same annulus in a different way than the space it sits in does: one point per direction rather than one point in total, which closes it into a Mobius band rather than a disk. That circle of directions is the line at infinity of RP2\RP^2, and the space of geodesics is the exterior of the unit conic there - which is where the Klein picture lived all along.

Happily we will never need a diameter. We are going to centre our polygons at the origin, so no side passes through the centre and every side is an honest circle. From here on we work in the exterior of the unit disk: a plane with a hole punched in it.

Regular Polygons and Their Duals

A geodesic is a point outside the disk, so a hyperbolic polygon is a finite set of points outside the disk - one for each side. Writing a polygon down has become the question of which finite sets of exterior points to look at, and if we ask for a regular polygon the answer is very nearly forced.

Regular means all pp sides the same length and all pp interior angles equal. Such a polygon has a centre, just as in the Euclidean plane. An isometry of H2\HH^2 is determined by what it does to three points in general position, so a symmetry of PP is pinned down by the permutation it makes of the vertices, and the symmetry group is finite. And a finite group of isometries of the hyperbolic plane always fixes a point: take any orbit, and the centre of the smallest disk containing it is unique, so every element of the group must preserve it. About that point the group acts as the dihedral group DpD_p, exactly as one expects.

So put that centre at the origin. The polygon is convex and its centre is inside it, so no side passes through the origin - the one case we promised ourselves we would never need - and all pp sides are honest circles, with honest exterior points c1,,cpc_1,\dots,c_p.

Now the reason for choosing this model. The isometries of H2\HH^2 fixing the centre of the Poincare disk are exactly the Euclidean rotations and reflections about it: a hyperbolic rotation by α\alpha about the origin is the map zeiαzz\mapsto e^{i\alpha}z, on the nose. So the symmetry carrying PP one step around itself, which permutes its sides cyclically, permutes the exterior points cic_i by an ordinary Euclidean rotation of order pp.

And pp points forming a single orbit of a rotation of order pp are the vertices of a regular Euclidean pp-gon. Reflection in the perpendicular dropped from the centre to a side is a symmetry too, fixing that side and hence its circle and hence its centre, so each cic_i lies on that line, aimed straight at the midpoint of its own side. A regular hyperbolic polygon inside the disk is a regular Euclidean polygon outside it, one outer vertex per inner side - which is exactly how a polygon stands to its dual - though in the plane that says little, the dual of a pp-gon being a pp-gon again.

Everything about the configuration is therefore settled once we say how big the outer polygon is. Write ρ\rho for its circumradius.

Pull ρ\rho in towards the boundary circle and the bounding circles shrink, the polygon swells, and its angle falls towards zero - the ideal pp-gon, with its corners out on the circle at infinity. Push ρ\rho out and the circles grow, the polygon shrinks towards the centre, and its angle climbs. One number in, one angle out. What we need is the dictionary between them.

Describing the Relationship

Everything happens at a vertex. Two adjacent sides of PP meet there at the interior angle θ\theta, and in our picture those two sides are two circles crossing.

So what we need is a relation between the angle at which two circles meet and the distance between their centres - and once we have it, the rest of the picture supplies everything else that goes into it.

We already have one instance of it. Orthogonality, r2+1=c2r^2+1=\|c\|^2, was Pythagoras applied to the triangle made of the two radii and the segment joining the centres. For a general angle that triangle is still there, and Pythagoras becomes the law of cosines.

There is one thing to be careful of, and it is the only place in the calculation where a sign can go wrong. The apex angle of the triangle is not θ\theta. The angle between two circles is the angle between their tangents at the crossing point, while the triangle is built out of radii - and each radius is perpendicular to its own tangent. Turning both tangents through a right angle turns θ\theta into its supplement:

χ=πθ\chi = \pi-\theta

So the law of cosines reads r12+r222r1r2cosχ=d2r_1^2+r_2^2-2r_1r_2\cos\chi=d^2, and substituting cosχ=cosθ\cos\chi=-\cos\theta,

r12+r22+2r1r2cosθ=d2r_1^2+r_2^2+2r_1r_2\cos\theta = d^2

which is the orthogonality relation again when θ=π/2\theta=\pi/2, as it had better be.

Now we have everything. Write δ=2π/p\delta=2\pi/p for the angle two adjacent exterior points subtend at the origin. Three facts meet at our vertex:

Feeding the first two into the angle relation,

2r2(1+cosθ)=ρ2(22cosδ)2r^2(1+\cos\theta) = \rho^2(2-2\cos\delta)

and then the third, we are left with one equation in the single unknown ρ\rho:

(ρ21)(1+cosθ)=ρ2(1cosδ)(\rho^2-1)(1+\cos\theta) = \rho^2(1-\cos\delta)

Expanding both sides and collecting the ρ2\rho^2 terms gives ρ2(cosθ+cosδ)=1+cosθ\rho^2(\cos\theta+\cos\delta)=1+\cos\theta, and that is the whole calculation:

TheoremBounding Circles of a Regular Polygon

A regular hyperbolic pp-gon of interior angle θ\theta, centred at the origin of the Poincare disk, is bounded by pp circles whose centres form a regular pp-gon of circumradius ρ\rho, where

ρ2=1+cosθcosθ+cosδ,δ=2πp\rho^2=\frac{1+\cos\theta}{\cos\theta+\cos\delta},\qquad \delta = \frac{2\pi}{p}

For instance the right-angled hexagon, p=6p=6 and θ=π/2\theta=\pi/2, has cosδ=12\cos\delta=\tfrac12 and so

ρ2=11/2=2,r2=ρ21=1\rho^2=\frac{1}{1/2}=2,\qquad r^2 = \rho^2-1=1

six unit circles, centred at the vertices of a regular hexagon of circumradius 2\sqrt2. That is the sort of answer we were after.

The formula also says where the family stops. Its denominator is positive only while θ+δ<π\theta+\delta<\pi, so a regular hyperbolic pp-gon of angle θ\theta exists precisely when θ<(p2)π/p\theta<(p-2)\pi/p - the interior angle of the Euclidean regular pp-gon. Approaching that value ρ\rho\to\infty and the circles flatten into straight lines; at the other end θ=0\theta=0, the vertices arrive on the boundary and adjacent circles become tangent, which is the ideal pp-gon and the largest one there is. So each pp gives a family running over θ[0,(p2)πp)\theta\in[0,\tfrac{(p-2)\pi}{p}), shrinking from ideal to nothing as the angle grows.

Which means we can now name a polygon by its angle and read off the radius that draws it:

Which Ones Tile

A polygon tiles H2\HH^2 face-to-face when a whole number of copies close up around each vertex. If qq of them do, they share the 2π2\pi of angle there equally, so

θ=2πq\theta = \frac{2\pi}{q}

and the tiling is the regular one with Schlafli symbol {p,q}\{p,q\}. Whether such a tiling exists is therefore just the question of whether 2π/q2\pi/q is an angle a hyperbolic pp-gon can have - and putting θ=2π/q\theta=2\pi/q into the condition of the last section,

2πq<(p2)πp    2p<q(p2)    1p+1q<12\frac{2\pi}{q} < \frac{(p-2)\pi}{p} \iff 2p < q(p-2)\iff \frac1p+\frac1q<\frac12

the classical condition, recovered as a range check.

When it holds the theorem hands over the coordinates with no further work: substituting θ=2π/q\theta=2\pi/q,

ρ=1+cos2πqcos2πq+cos2πp,r=ρ21\rho=\sqrt{\frac{1+\cos\frac{2\pi}q}{\cos\frac{2\pi}q+\cos\frac{2\pi}p}},\qquad r=\sqrt{\rho^2-1}

and the tile is the part of the disk outside the pp circles of radius rr centred at ρ(cos2πkp,sin2πkp)\rho\,(\cos\tfrac{2\pi k}{p},\,\sin\tfrac{2\pi k}{p}). Some of the small cases come out cleanly:

tilingρ2\rho^2r2r^2
{6,4}\{6,4\}2211
{4,6}\{4,6\}3322
{5,4}\{5,4\}1+51+\sqrt55\sqrt5
{8,3}\{8,3\}1+21+\sqrt22\sqrt2
{7,3}\{7,3\}4.048924.048923.048923.04892

The right-angled pentagon {5,4}\{5,4\} is the one from an earlier note, which found it by placing geodesics in the upper half plane one at a time; here it arrives all at once, as five circles of radius 51/45^{1/4}.

To see which {p,q}\{p,q\} occur, draw each pp as the interval of angles its polygons can have and mark the angles 2π/q2\pi/q across it. Every crossing is a tiling.

Picking a crossing out of that picture gives the tiling itself, and the condition made visible - qq copies closing up around a vertex because each has angle 2π/q2\pi/q there:

This has infinitely many answers. The angles 2π/q2\pi/q pile up towards zero and every bar runs down to zero, so each pp is crossed infinitely often: for any p3p\geq3 all sufficiently large qq work, and for any q3q\geq3 all sufficiently large pp do. The hyperbolic plane is not short of regular tilings.

Which Are Reflection Groups

Reflection in the line carrying a side is a symmetry of {p,q}\{p,q\} for every qq, which is how any of these tilings is drawn - reflect one polygon in its own sides until the disk fills up. What the parity of qq decides is something else: whether the polygon is a Coxeter polygon, meaning all of its angles are π/m\pi/m for a whole number mm. Since θ=2π/q\theta=2\pi/q, that happens exactly when qq is even.

Those are the ones where the polygon is a genuine fundamental chamber, and where the tiling can be two-coloured by the parity of the number of reflections it takes to reach a tile:

The odd qq are no less real as tilings; their polygons are simply not chambers, and there is no such two-colouring.

In Code

That picture is not a list of polygons. Reflecting a tile into its neighbours a dozen deep still leaves the disk visibly empty near the boundary, which is exactly where the tiles are smallest and most numerous, and going deeper costs exponentially more for less and less screen. So it runs the other way round: take a pixel and push it back into the fundamental polygon, counting the reflections. Every pixel costs about the same, and the tiling is drawn to the horizon.

Everything needed is already in hand. The walls are the pp circles of the recipe above, and a hyperbolic reflection in one of them is an ordinary Euclidean inversion,

vec2 reflectIn(vec2 z, vec2 c, float r2) {
    vec2 d = z - c;
    return c + r2 * d / dot(d, d);
}

The polygon is the part of the disk outside every wall, so a point is home exactly when no wall contains it - which makes the fold a loop with an obvious stopping condition:

int fold(inout vec2 z, float rho, float r2) {
    int word = 0;
    for (int step = 0; step < 120; step++) {
        bool moved = false;
        for (int i = 0; i < MAXP; i++) {
            if (float(i) >= pCount) break;
            vec2 c = wallCentre(i, rho);
            if (inside(z, c, r2)) {
                z = reflectIn(z, c, r2);
                word++;
                moved = true;
            }
        }
        if (!moved) break;
    }
    return word;
}

word is the number of reflections, and its parity is the two-colouring. The only other thing worth naming is the edge weight: a tile near the boundary is a few pixels across, so drawing edges by Euclidean width makes them swallow the tile. Measuring the hyperbolic distance to the nearest wall instead gives every edge the same weight wherever it is:

float wallDist(vec2 z, vec2 c, float r2) {
    vec2 d = z - c;
    return abs(dot(d, d) - r2) / (sqrt(r2) * (1.0 - dot(z, z)));
}

Here is the whole program. Set pp and qq at the top and it draws that tiling; on the page above those two are the buttons.

// The {p, q} tiling of the Poincare disk, one pixel at a time.
// Choose the tiling here: q even, and 1/p + 1/q < 1/2.
const float pCount = 5.0;   // sides of the polygon
const float qCount = 4.0;   // copies meeting at each vertex

const int MAXP = 12;
const float PI = 3.14159265359;
const float TAU = 6.28318530718;

// rho^2 = (1 + cos theta)/(cos theta + cos delta), with theta = 2pi/q the
// interior angle and delta = 2pi/p the angle between adjacent centres. Every
// wall is orthogonal to the boundary, so r^2 = rho^2 - 1.
float outerRadius2() {
    float theta = TAU / qCount;
    float delta = TAU / pCount;
    return (1.0 + cos(theta)) / (cos(theta) + cos(delta));
}

// The p exterior points, turned half a step so a vertex points along the x axis.
vec2 wallCentre(int i, float rho) {
    float a = PI / pCount + TAU * float(i) / pCount;
    return rho * vec2(cos(a), sin(a));
}

bool inside(vec2 z, vec2 c, float r2) {
    vec2 d = z - c;
    return dot(d, d) < r2;
}

vec2 reflectIn(vec2 z, vec2 c, float r2) {
    vec2 d = z - c;
    return c + r2 * d / dot(d, d);
}

int fold(inout vec2 z, float rho, float r2) {
    int word = 0;
    for (int step = 0; step < 120; step++) {
        bool moved = false;
        for (int i = 0; i < MAXP; i++) {
            if (float(i) >= pCount) break;
            vec2 c = wallCentre(i, rho);
            if (inside(z, c, r2)) {
                z = reflectIn(z, c, r2);
                word++;
                moved = true;
            }
        }
        if (!moved) break;
    }
    return word;
}

float wallDist(vec2 z, vec2 c, float r2) {
    vec2 d = z - c;
    return abs(dot(d, d) - r2) / (sqrt(r2) * (1.0 - dot(z, z)));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 z = (2.0 * fragCoord - iResolution.xy) / min(iResolution.x, iResolution.y) * 1.06;
    if (dot(z, z) >= 1.0) { fragColor = vec4(0.96, 0.95, 0.92, 1.0); return; }

    float rho2 = outerRadius2();
    float rho = sqrt(rho2);
    float r2 = rho2 - 1.0;

    int word = fold(z, rho, r2);

    float s = 1e9;
    for (int i = 0; i < MAXP; i++) {
        if (float(i) >= pCount) break;
        s = min(s, wallDist(z, wallCentre(i, rho), r2));
    }

    vec3 tile = (word % 2 == 0) ? vec3(0.20, 0.45, 0.70) : vec3(0.80, 0.62, 0.18);
    vec3 col = mix(vec3(0.96, 0.95, 0.92), tile, word == 0 ? 0.55 : 0.26);
    col = mix(vec3(0.15, 0.15, 0.16), col, smoothstep(0.0, 2.0 * fwidth(s) + 0.010, s));

    fragColor = vec4(col, 1.0);
}

Nothing in it knows about hyperbolic geometry beyond two facts from the start of this note: a geodesic is a circle orthogonal to the boundary, and reflecting in one is inversion. The rest is the recipe.

One Dimension Up

Nothing in the argument was two-dimensional. Planes of the Poincare ball are spheres orthogonal to its boundary, named by a single exterior point in exactly the same way, and the same two relations fix the scale of a regular polyhedron centred at the origin. That calculation is here, where the count at the end comes out finite: eight.

← All notes