Day 3: Hyperbolic Tilings — Homework
Checkpoints
These verify you've understood the core material.
C1. Custom Palette. Change the color scheme of any tiling shader. Replace CREAM and SLATE with your own colors. Try high contrast, low contrast, or complementary colors. Which combinations make the structure easiest to see?
C2. Growing Tiling. Animate the fold count limit to watch the tiling build up layer by layer:
int max_iter = int(mod(iTime * 10.0, 100.0)) + 1;
Apply this to the Poincaré disk shader. Watch each iteration reveal a new ring of triangles.
C3. The (2,4,5) Triangle. The
Here are the half-spaces:
HalfSpaceVert left = HalfSpaceVert(0.0, -1.0); // x > 0
HalfSpaceCirc bottom = HalfSpaceCirc(0.0, 1.0, 1.0); // outside unit circle
HalfSpaceCirc third = HalfSpaceCirc(-1.70, 2.40, -1.0); // inside this circle
Implement this tiling in the Poincaré disk. How does it differ visually from
C4. F Markers in (2,3,7). Add the drawF function to the z - vec2(0.15, 1.1) as a starting point and adjust until the F sits nicely inside the triangle.
C5. Rainbow Tiling. Instead of parity (two colors), color by the full fold count using a smooth rainbow:
float t = float(foldCount) / 20.0;
vec3 color = 0.5 + 0.5 * cos(6.28318 * (t + vec3(0.0, 0.33, 0.67)));
What structure does this reveal that parity coloring hides?
Explorations
These extend the day's topics in interesting directions.
E1. Hyperbolic Circles. In hyperbolic geometry, circles look different depending on where they are. The hyperbolic distance formula in the upper half-plane is:
In GLSL: acosh(x) = log(x + sqrt(x*x - 1.0)).
Draw hyperbolic circles around a fixed point (say,
Then make the center follow the mouse. Notice how circles stretch horizontally and compress vertically near the boundary—this is the hyperbolic metric at work.
E2. Dragging a Hyperbolic Ball. On Day 1, we dragged a Euclidean circle with the mouse. Do the same in hyperbolic space:
Map mouse position to the upper half-plane
Draw a filled hyperbolic disk of radius 0.3 centered at the mouse
All points within hyperbolic distance 0.3 should be colored
Watch how the "ball" distorts as you drag it toward the real axis—it gets enormous in Euclidean terms but stays the same hyperbolic size.
Extension: Implement this in the Poincaré disk model. You'll need to convert mouse position through the Cayley transform.
E3. Edge Highlighting. Instead of coloring tiles by parity, color by distance to an edge of the fundamental domain. After folding, compute the distance to one of the boundary lines (Euclidean distance is fine for the Euclidean triangle tiling) and use it for coloring:
float distToEdge = /* distance to bottom edge */;
float brightness = smoothstep(0.0, 0.3, distToEdge);
vec3 color = mix(vec3(1.0), SLATE, brightness);
For the equilateral triangle tiling, this creates a pattern of highlighted "stripes" that trace through the tiling—making hexagonal shapes visible even though we're drawing triangles!
Try the same for hyperbolic tilings (using hyperbolic distance). What patterns emerge?
E4. Edges of the Tiling. Add edge drawing to any hyperbolic tiling. After folding, check distance to each geodesic boundary and draw white where distance is small.
For a vertical geodesic at
float distToVert(vec2 z, float c) {
z.x -= c;
return acosh(length(z) / z.y);
}
For a semicircular geodesic, use a Möbius transformation that sends it to a vertical line:
float distToCirc(vec2 z, float center, float radius) {
vec2 num = z - vec2(center + radius, 0.0);
vec2 denom = z - vec2(center - radius, 0.0);
vec2 w = cdiv(num, denom);
return acosh(length(w) / w.y);
}
The edges should have constant hyperbolic thickness—fanning out near the boundary in Euclidean terms.
E5. Soccer Ball Coloring. The
After folding, determine which vertex of the fundamental domain your point is closest to (in hyperbolic distance). Color differently based on vertex type:
Near the
vertex: white𝜋 / 2 Near the
vertex: black𝜋 / 3 Near the
vertex: white𝜋 / 7
This highlights the
Challenges
These require ideas beyond the lecture.
H1. The Klein Disk Model. The Klein disk represents hyperbolic space where geodesics appear as straight Euclidean lines. This makes some properties obvious but distorts angles.
Conversions:
Poincaré → Klein:
𝑘 = 2 𝑤 1 + | 𝑤 | 2 Klein → Poincaré:
𝑤 = 𝑘 1 + √ 1 − | 𝑘 | 2
Display the
H2. The Band Model. The band model maps hyperbolic space to an infinite horizontal strip of height
From the Poincaré disk:
In GLSL:
vec2 poincareToBand(vec2 w) {
vec2 num = vec2(1.0, 0.0) + w;
vec2 denom = vec2(1.0, 0.0) - w;
vec2 ratio = cdiv(num, denom);
return vec2(0.5 * log(dot(ratio, ratio)), atan(ratio.y, ratio.x));
}
Display the tiling in the band model. Horizontal translation in the band corresponds to hyperbolic translation along a geodesic!
H3. Interactive Möbius Transformations. Hyperbolic isometries are Möbius transformations
Useful ones:
Horizontal translation:
𝑧 ↦ 𝑧 + 𝑡 Scaling:
𝑧 ↦ 𝑘 𝑧 Rotation around
:𝑖 𝑧 ↦ 𝑧 c o s ( 𝜃 / 2 ) + s i n ( 𝜃 / 2 ) − 𝑧 s i n ( 𝜃 / 2 ) + c o s ( 𝜃 / 2 )
Make the tiling interactive: mouse x controls translation, mouse y controls scaling. The tiling slides and zooms while preserving its structure.
Project: General Triangle Tilings
Build a shader that tiles the hyperbolic plane with any triangle
Part A: Understanding the Setup
We place the triangle conveniently in the upper half-plane:
The
vertex sits where the vertical geodesic𝜋 / 𝑝 meets the unit circle𝑥 = − c o s ( 𝜋 / 𝑝 ) One edge lies along the unit semicircle
One edge lies along a vertical geodesic
For
Part B: Computing the Third Geodesic
The hyperbolic law of cosines gives the side length
From here, we can find the Euclidean height of the third vertex (it lies hyperbolic distance
Hint: draw yourself some constructions in Eulidean geometry!
Exercise: Given your general formula, work through this calculation for center ≈ -0.7665 and radius ≈ 1.533.
Part C: Implementation
Write a function that takes 2, q, r as parameters and returns the third half space. Then build the tiling with adjustable parameters (say, constants that are set at the top of the file? Or animated by iTime? Or controlled by iMouse?)
Part D: Visualization
Add edges and vertices. Color vertices by their angle type (
Display in both the upper half-plane and Poincaré disk models.
Part E: Gallery
Create a gallery of tilings—render several interesting examples:
,( 2 , 3 , 7 ) ,( 2 , 3 , 8 ) , ... — increasing the third parameter( 2 , 3 , 9 ) ,( 2 , 4 , 5 ) ,( 2 , 4 , 6 ) , ...( 2 , 4 , 7 ) ,( 3 , 3 , 4 ) — no right angles (requires generalizing Part B!)( 3 , 3 , 5 )
Which parameters produce the most visually striking tilings? What happens as one parameter approaches infinity?
Extra Challenge: The General (p,q,r) Case
When
Generalize your implementation to handle arbitrary