Patterns in the Poincaré Plane - Geometry Nodes: Part 2

Last post I covered drawing geodesic lines (they look like circle arcs) on the Poincaré Disk. This time I’m going to cover drawing hyperbolic tilings. See this blend file for the node groups and assets.

Circle Inversion

The next maths step is finding the reflection of a point in the geodesic. Inversive geometry - Wikipedia

circle reflect geogebra

In the above diagram $D^\prime$ is the point $D$ reflected in the arc-line circle. $D^\prime$ lies on the line $CD$, where $C$ is the centre of the arc-line circle (coordinates $(x_0, y_0)$). The inversion position of this point along the line is defined such that :

\[|CD| \cdot |CD^\prime| =r^2\]

or in coordinate geometry:

\(m = \frac{r^2}{(x-x_0)^2 + (y-y_0)^2}\)\(x^\prime = x_0 + m(x-x_0)\) \(y^\prime=y_0+m(y-y_0)\) or in math formula extension syntax:

ng reflect_point_circle(point:vec3, center:vec3, radius:float)-> reflect_point:vec3 { 
 m = radius**2.0/(dist(point, center)**2.0);
 d = sub(point, center);
 out reflect_point = center + scale(d, m);
 }
 reflect_point_circle({0.5, 0.5, 0.0}, {0.,0.,0.}, 1.0);

I end up with this node group.

reflect-point-circle node group

Check this by drawing a diagram similar to the GeoGebra one above.

reflect point circle blender

Mirror a single face in the edge of a polygon

Next lets mirror an entire face in the circle.

face reflect blender

The smallest 7-gon is the mirror image of the central 7-gon in one of its edges using circle inversion. For comparison, the euclidean reflection is also shown.

mirror face nodes

Calculate the size of the central polygon

The central polygon of a hyperbolic tiling must have a specific radius $d$ depending on $p$ the number of vertices of each polygon, and $q$ the number of polygons (or edges) meeting at each vertex.

\[d = \sqrt{ \frac{ \tan\left( \frac{\pi}{2}-\frac{\pi}{q} \right)-\tan\left( \frac{\pi}{p} \right) } { \tan\left( \frac{\pi}{2} - \frac{\pi}{q} \right) + \tan\left( \frac{\pi}{p}\right) } }\]

see Non-Euclidean Geometry: Interactive Hyperbolic Tiling in the Poincaré Disc for a derivation of this.

Math formula extension syntax

ng radius_center_n_gon(p:int, q:int) -> euclidean_radius: float {
	tq=tan(#(pi/2)-#pi/q);
	tp=tan(#pi/p);
	out euclidean_radius = sqrt((tq-tp)/(tq+tp));
}
radius_center_n_gon(7, 3);

radius n-gon node group

Mirror the adjacent face for all boundary edges

Next I wrap this up as a group that loops over all boundary edges, finds the adjacent face and reflects it in the edge.

mirror all boundary edges nodes

Tiling

Combining all these steps to create a tiling of the Poincaré Disk. Recap Groups created - names as in the accompanying blend file.

  • “geodesic” - find the centre and radius of the geodesic through two points on the Poincaré Plane
  • “reflect-point-circle” - find the position of a point mirrored in a geodesic
  • “radius-center-n-gon”
  • “mirror-adjacent-faces-poincare” - mirror - the adjacent face for all boundary edges

tiling nodes

7,3 poincare tiling straight edges

For ease, the edges of the polygons are plotted as a straight lines. They should, of course, be arcs. I’ll look at replacing the edges with geodesic segments in Part 3 of this series. In that post I’ll also show how to move the start polygon away from the centre.

Subdividing tiling

Lots of fun can be had by adding triangulate, dual, and subdivide nodes to the tiling output.

subdivide 1

subdivide 2

subdivide 3

subdivide 4

This is related to Conway Operators which is another thing I’ve been playing with in Geometry Nodes. I’ll write it up here eventually.