Poincare meets Mandelbrot

Other stuff by be
PoincarePoincare disc                                      Mandelbrot 3D print  Benoit Mandelbrot (Wikipedia photo By Steve Jurvetson)

I wanted to tile the Mandelbrot set with a hyperbolic tiling. I thought about various methods, and decided to do one using circle packings, which happens to be a third a subject I like. So with 3 subjects I like coming together,  a cool project was born. This web page is to give a bit more explanation than just the pictures themselves.

I chose as title 'Poincare meets Mandelbrot'. Although Poincare was not the first to discover the 'Poincare disc', he is easily cool and famous enough to still be in the title. (For example, he discovered chaos in the 3 body problem)

One way to describe what the Poincare disc is, is to take a triangle formed by circle segments, whose angles at the vertices are whole number divisions of 2π, for example in the above picture I use (π/7, π/3, π/2). Then you generate new triangles by repeatedly inverting triangles in one of of the sides, using circle inversion.
If  (π/a + π/b + π/c) > π, then you get an elliptic tiling.
If  (π/a + π/b + π/c) = π, then you get a parabolic tiling
If  (π/a + π/b + π/c) < π, then you get a hyperbolic tiling
Check out another web page of mine for many examples of these.
We have π/7 + π/3 + π/2 = π*41/42, so that is hyperbolic. In fact, it is the closest of all hyperbolic tilings to being non-hyperbolic, which is why it is probably the prettiest. The others tend to have large differences in sizes of neighboring triangles.

For hyperbolic tilings, it turns out that all the triangles end up a disc, which they asymptotically fill: near the edge the triangles become infinitely small.
That is the Poincare disc. It has many more interesting properties, but here we just focus on tilings.

The Mandelbrot set is a famous fractal. It has an inifinitely ddetailed structure, yet is generated by a very simple formula: z -> z2 + z0
z is complex number, but you can interpret the coordinates of pixel on you screen as the components (x0,y0) of the complex number z0= (x0+iy0).
You start iterating z ->  z0 -> z2 + z0 -> (z2 + z0)2 + z0-> ((z2 + z0)2 + z0)2 + z->...
Or, splitting up z into its components
    x -> x0 -> (x2 - y2) + x0 ->...
    y -> y0 -> (2xy) + y0 ->...
Doing this iteration for a number of steps, you can end up going to infinity. In fact, once you get larger than (x2 + y2) =4, you can conclude that you are doomed to 'escape' to infinity.
The Mandelbrot set is the set of all points that do not escape to infinity. It is not so hard to write a computer program that generates the Mandelbrot set. An extra thing you can do is note the number of iterations it took for you to conclude that it would escape to infinity. This gives the escape rings. On the 3D print photo at the top of the page, you can see these some of these rings. We will use them later.

To map the Poincare disc onto the interior of the Mandelbrot set, we can use circle packings. The idea of a circle packing, is to create a connectivity network of circles and then demand that they all touch. You are allowed to vary the radii. It turns out that solutions exist for a wide range of situations.

To solve the packing, one algorithm is to calculate the angular deficit at each circle. In the figure below, we chose a particular circle, and constructed triangles from lines from its scene to the centers of its neighbors. We know the lengths of these lines: They are just ri+rj for circles i and j. From the lengths we can calculate the angles of the triangles using the cosine law.:
cos(alfa12) = ( (r0+r1)2 + (r0+r2)2) - (r1+r2)2 ) / (2 (r0+r1) ((r0+r2))
If the circles all touch, then the sum of the angles at each vertex, should be 2π.
If it is larger, we shrink the circle, if it is smaller, we expand the circle. That process seems to converge well to a solution, in all cases I know.

Circle Packing
On the edges the angles do not need to sum, so we can think of something else. In our case, we are going to tell them to be in a particular escape ring of the Mandelbrot. How do we know? Well, we just take the coordinates of the circle center, plug them in the Mandelbrot iteration, and see how long it takes them to escape to infinity. If it takes too long, make the circle larger, and vice versa.

CirclePackingAnaimationCirclePacking Animation
Above is an animation I made years ago, showing how circle packings can adapt to shape.
For more on circle packings, check out the web page of Kenneth Stephenson.

Creating a (7,3) connectivity network.

To get going, we need to tell each circle what its neighbors are. This seems initially quite messy, but the solution is nice, involving Fibonacci numbers.
Looking at the (7,3) tiling, we note that it can be organized into concentric rings of heptagons (circles and heptagons are interchanged here). I call each ring a Generation. Generation(0) is the central heptagon. Generation(1) is a ring of 7 heptagons. In Generation(2), we notice there are 2 different neighbor structures for the heptagons:
Type A has 1 'parents', 2 'sisters', and 4 'children' of who 1 type B, 2 type A ,and a type B which we don't count to avoid double counting children with 2 parents'.
Type B has 2 'parents', 2 'sisters', and 3 'children' of who 1 type B, 1 type A ,and a type B which we don't count to avoid double counting children with 2 parents'.
Generation(1) was all Type A.

To count how many we get for each generation, we write down:
    Ai+1 = 2*Ai + Bi
    Bi+1 = Ai + Bi
If we initialise with 1,0 we get Fibonacci numbers (with a bit of effort, you can prove this):
Fibonacci table       
So our generations will contain 7-folds of Fibonacci numbers of members.
You can derive the total number of heptagons:
    nHepta = 1+7 * (Fibonacci(2 * (Ngenerations) + 1) - 1)

If we number the members of a generations counterclockwise, this is a number scheme that will navigate us through  neighbor administration hell.
Neighbour table

Lets Go!

If we bias the edge cells to be on a circle of a given circle, we get the Poincare disc:
Circle Packed Poincare
To make things a bit easy for our cells, lets first tell them to go to a low escape ring, say 7. This escape rings get more and more twisty and complex as they get higher (closer to the Mandelbrot).
Escape ring 7
One thing visible in the above picture is that in this case the number of cells is too small to penetrate into the main filament.

Increasing the escape ring to about 50:
Hyperbolically tiled Mandelbrot

Or we can render the circles as balls:
Indra pearl Mandelbrot

Make a Julia set:

Julia set tiled with hyperbolic tiling