Skip to content
Sample of Poincaré Disk Hyperbolic Tessellation

openprocessing_p5js · HyperbolicTiling

Poincaré Disk Hyperbolic Tessellation

Escher-style regular hyperbolic tessellation in the Poincaré disk. Builds the {p, q} tiling where p-sided regular polygons meet q at every vertex, valid only when (p-2)(q-2) > 4. Implemented as recursive Möbius reflection: start with a central p-gon, draw it, then for each edge reflect the central polygon across the geodesic that edge subtends, recursing depth times.

Original: https://github.com/looeee/hyperbolic-tiling

▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.

Family
openprocessing_p5js
Source
openprocessing · p5.js
Evolution
tiling
Render
recursive_polygon_outline
Complexity
high
Agents
1
Year
1995
Author
M.C. Escher (Circle Limit, 1958-60); David Joyce's Hyperbolic Tessellations applet (1995); b5strbal/Escher (2020); community (OpenProcessing)

Math essence

Reflection across a geodesic whose endpoints on the unit circle are (a, b): R(z) = (c*conj(z) + (a-b)*a) / (conj(c)*z + conj((a-b)*a)) where c = (a-b) / (1 - conj(a)*b). Central polygon radius: cosh(rho) = cos(pi/q) / sin(pi/p). Schlafli deficit: (p-2)(q-2) > 4 required for hyperbolic geometry.

Parameters

Name Type Default Range Description
dim int 512 200–1200 Square canvas side length.
p int 7 3–24 Polygon sides per cell.
q int 3 3–24 Cells meeting at each vertex.
depth int 4 1–8 Reflection recursion depth.
line_alpha float 0.85 0.05–1 Edge opacity per stamp.
bg_color tuple 245,240,230 — Background canvas color.
ink_color tuple 24,28,56 — Edge color.
max_polys int 3500 100–20000 Polygons cap (truncates BFS if exceeded).
seed int null 0–999999

Reference

First 60 lines of reference.py. Full source: library_external/openprocessing_p5js/HyperbolicTiling/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


def _mobius_reflect_point(z: complex, a: complex, b: complex) -> complex:
    """Reflect complex point ``z`` across the geodesic line through points
    ``a`` and ``b`` (inside the unit disk).

    A Poincaré-disk geodesic is a Euclidean circle orthogonal to the unit
    circle. Given two interior points a, b, the unique such circle passing
    through them has center ``c`` on the perpendicular bisector of ab with
    the orthogonality constraint ``|c|^2 = |c - a|^2 + 1``. Solving:

        Re(conj(a) c) = (|a|^2 + 1) / 2
        Re(conj(b) c) = (|b|^2 + 1) / 2
        Im(conj(a) c - conj(b) c) free

    This is a 2×2 linear system in the real and imaginary parts of c. The
    reflection is then inversion in that circle:

        R(z) = c + |c - a|^2 / conj(z - c)

    Used by Joyce's Hyperbolic Tessellations applet (1995), b5strbal/Escher
    (2020), and Beardon, *The Geometry of Discrete Groups*, §3.
    """
    if abs(a - b) < 1e-12:
        return z
    aa = abs(a) ** 2
    bb = abs(b) ** 2
    rhs_a = (aa + 1.0) * 0.5
    rhs_b = (bb + 1.0) * 0.5
    A = np.array(
        [
            [a.real, -a.imag],
            [b.real, -b.imag],
        ],
        dtype=np.float64,
    )
    rhs = np.array([rhs_a, rhs_b], dtype=np.float64)
    try:
        sol = np.linalg.solve(A, rhs)
    except np.linalg.LinAlgError:
        return z
    c = complex(sol[0], sol[1])
    rho2 = abs(c - a) ** 2
    dz = z - c
    if abs(dz) < 1e-12:
        return z
    return c + rho2 / np.conj(dz)


class HyperbolicTiling:
    """Escher-style regular hyperbolic tessellation in the Poincaré disk.

    Builds the ``{p, q}`` tiling where ``p``-sided regular polygons meet
    ``q`` at every vertex, valid only when the Schlafli angle deficit
    ``(p - 2)(q - 2) > 4``. Implemented as a recursive reflection scheme in

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/openprocessing_p5js/HyperbolicTiling/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from openprocessing · p5.js

See all openprocessing_p5js artworks →