Mobius transformations in hyperbolic 3-space



  1. pyglet for the UI and OpenGL environment.
  2. ffmpeg for rendering the animation to video files.

This project is exported and adapted from Roice Nelson's code at shadertoy, thanks for his nice aniamtion! You may refer to Roice's homepage for more explanations on the math behind the scenes.


Simply run and use keyboard to switch between the several scenes.

Mobius transformations and isometry of the hyperbolic 3-space

Mobius transformations are also called fractal linear transformations of the extended complex plane \(\hat{\mathbb{C}}\):

\[M(z) = \frac{az+b}{cz+d}, \quad a,b,c,d,z\in\hat{\mathbb{C}}.\]

\(M\) can be decomposed into "building blocks" of 4 types:

  1. \(M\) is called parabolic if it's conjugate to a pure translation \(z\to z+a\) where \(a\in\mathbb{C}\).
  2. \(M\) is called elliptic if it's conjugate to a pure rotation \(z\to e^{i\theta}z\) where \(\theta\in\mathbb{R}\).
  3. \(M\) is called hyperbolic is it's conjugate to a pure scaling \(z\to \lambda z\) where \(\lambda\in\mathbb{R}\) and \(\lambda>0\).
  4. \(M\) is called loxodromic is it's a composition of a hyperbolic transformation and a elliptic transformation, i.e. \(z\to cz\) where \(c\in\mathbb{C}\).

Each Mobius transformation can be uniquely extended to an isometry of the upper hyperbolic halfspace \(H_3=\{(x,y,z)\in\mathbb{R}^3\ |\ z>0\}\). This can be easily defined by using quaternions: let \(M=(az+b)/(cz+d)\) be a Mobius transformation and \(p=(x,y,z)\in H_3\), let \(q\) be the quaternion \(q=x+yi+zj\), then define \[M(p) = \frac{aq+b}{cq+d}.\]

  1. If \(M\) is of parabolic type then the extended isometry has one fixed point at \(\infty\).
  2. If \(M\) is of elliptic type then the extended isometry has two fixed points and it's a rotation around the axis connecting the two points.
  3. If \(M\) is of hyperbolic type then the extended isometry also has two fixed points but it's a scaling that looks like "emitting" from one source and "sinking" into the other one.
  4. If \(M\) is of loxodromic type then it's a compostion of the elliptic and hyperbolic type.

One can also use a Mobius transformation to "invert" the cone into a Dupin cyclide, in this case the two fixed points \(0\) and \(\infty\) become the two "horns" of the cyclide.

How the scene is drawn

The scene is rendered by raymarching and GLSL: in each raymarching step we compute the distance between current point and the scene. Especially to compute the distance between a point \(p\) and the Dupin cyclide \(C\), one just transform \(C\) back to the cone by applying \(M^{-1}\), and transform \(p\) to \(q=M^{-1}(p)\), then compute the distance between the cone and \(q\). If in some step we have found that \(q\) has "hit" the cone then we think \(p\) has also hit the cyclide, then we color this "hitting point" by the coordinates of \(q\).