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 , 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
for a unit normal and a signed distance , and the only redundancy is that and name the same line. So the space of lines is the cylinder modulo an involution which is antipodal on the circle and a reflection on the . 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 , so the space of geodesics of the hyperbolic plane is that same band with narrowed to .
Now for the coordinates. The pair is not quite one, since it is only defined up to sign. But as long as we can divide the ambiguity away:
is unchanged by , and . So every geodesic except those with is named by a single honest point outside the unit disk. The lines with 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 outside the disk, draw the two tangent lines from to the boundary circle; the chord joining the two points of tangency is , 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 whose centres are a distance apart are orthogonal when , by the Pythagorean theorem, so against the unit circle a circle of centre and radius is a geodesic exactly when
The radius is not a second piece of data: , which is the length of the tangent from to the unit circle. Swinging that tangent segment around sweeps out precisely the circle we want.
And it is the same . The orthogonal circle centred at meets the boundary where and , and expanding that second equation gives - the same two points the tangents touched. So the Klein chord and the Poincare arc assigned to 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.
Geodesics of the hyperbolic plane not passing through the centre correspond exactly to points with . In the Klein model the geodesic is the chord ; in the Poincare disk it is the arc, inside the disk, of the circle centred at with radius the tangent length .
That leaves the geodesics with , which are the diameters. As a geodesic straightens towards one, runs off to infinity, and it does so in a definite direction: writing , the circle is , which as becomes the diameter perpendicular to . Opposite directions give the same diameter, so to finish the parameterization we glue on one point for each direction , with .
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 , 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 . 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 , 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 sides the same length and all interior angles equal. Such a polygon has a centre, just as in the Euclidean plane. An isometry of is determined by what it does to three points in general position, so a symmetry of 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 , 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 sides are honest circles, with honest exterior points .
Now the reason for choosing this model. The isometries of fixing the centre of the Poincare disk are exactly the Euclidean rotations and reflections about it: a hyperbolic rotation by about the origin is the map , on the nose. So the symmetry carrying one step around itself, which permutes its sides cyclically, permutes the exterior points by an ordinary Euclidean rotation of order .
And points forming a single orbit of a rotation of order are the vertices of a regular Euclidean -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 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 -gon being a -gon again.
Everything about the configuration is therefore settled once we say how big the outer polygon is. Write for its circumradius.
Pull in towards the boundary circle and the bounding circles shrink, the polygon swells, and its angle falls towards zero - the ideal -gon, with its corners out on the circle at infinity. Push 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 meet there at the interior angle , 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, , 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 . 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 into its supplement:
So the law of cosines reads , and substituting ,
which is the orthogonality relation again when , as it had better be.
Now we have everything. Write for the angle two adjacent exterior points subtend at the origin. Three facts meet at our vertex:
- the two circles have the same radius , since the sides of are congruent;
- their centres are the two ends of an edge of the outer -gon, so , which is to say ;
- each circle is orthogonal to the boundary, so .
Feeding the first two into the angle relation,
and then the third, we are left with one equation in the single unknown :
Expanding both sides and collecting the terms gives , and that is the whole calculation:
A regular hyperbolic -gon of interior angle , centred at the origin of the Poincare disk, is bounded by circles whose centres form a regular -gon of circumradius , where
For instance the right-angled hexagon, and , has and so
six unit circles, centred at the vertices of a regular hexagon of circumradius . That is the sort of answer we were after.
The formula also says where the family stops. Its denominator is positive only while , so a regular hyperbolic -gon of angle exists precisely when - the interior angle of the Euclidean regular -gon. Approaching that value and the circles flatten into straight lines; at the other end , the vertices arrive on the boundary and adjacent circles become tangent, which is the ideal -gon and the largest one there is. So each gives a family running over , 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 face-to-face when a whole number of copies close up around each vertex. If of them do, they share the of angle there equally, so
and the tiling is the regular one with Schlafli symbol . Whether such a tiling exists is therefore just the question of whether is an angle a hyperbolic -gon can have - and putting into the condition of the last section,
the classical condition, recovered as a range check.
When it holds the theorem hands over the coordinates with no further work: substituting ,
and the tile is the part of the disk outside the circles of radius centred at . Some of the small cases come out cleanly:
| tiling | ||
|---|---|---|
The right-angled pentagon 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 .
To see which occur, draw each as the interval of angles its polygons can have and mark the angles across it. Every crossing is a tiling.
Picking a crossing out of that picture gives the tiling itself, and the condition made visible - copies closing up around a vertex because each has angle there:
This has infinitely many answers. The angles pile up towards zero and every bar runs down to zero, so each is crossed infinitely often: for any all sufficiently large work, and for any all sufficiently large 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 for every , 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 decides is something else: whether the polygon is a Coxeter polygon, meaning all of its angles are for a whole number . Since , that happens exactly when 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 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 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 and 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.