Mark’s Math
  • Scholarship
  • Viz
  • Class
  • Legacy

Möbius transformations revealed

An interactive version of Möbius transformations revealed

import {xySlider, mobiusRevealedThree} from "./mobiusRevealedThree.js";
viewof sphereMotion = Inputs.form({
  phi: Inputs.range([0, Math.PI], {
    value: 0,
    step: 0.001,
    label: tex`\varphi`,
    format: value => value.toFixed(3)
  }),
  theta: Inputs.range([0, 2*Math.PI], {
    value: 0,
    step: 0.001,
    label: tex`\theta`,
    format: value => value.toFixed(3)
    // format: value => String(Math.max(-Math.PI, Math.min(Math.PI, +value.toFixed(3))))
  }),
  psi: Inputs.range([0, 2*Math.PI], {
    value: 0,
    step: 0.001,
    label: tex`\psi`,
    format: value => value.toFixed(3)
  }),
  z: Inputs.range([-2, 3], {
    value: 0,
    step: 0.01,
    label: tex`z`,
    format: value => value.toFixed(2)
  }),
  viewMode: Inputs.radio(["3D", "Top"], {
    value: "3D",
    label: "view"
  })
})

\(x\text{-}y\)

viewof xy = xySlider({
  xmin: -6,
  xmax: 6,
  ymin: -6,
  ymax: 6,
  xstep: 0.02,
  ystep: 0.02,
  value: [0, 0],
  width: "180px",
  height: "180px"
})
mobius_scene = mobiusRevealedThree()
phi = sphereMotion.phi
theta = sphereMotion.theta
psi = sphereMotion.psi
z = sphereMotion.z
viewMode = sphereMotion.viewMode
mobius_scene.update({phi, theta, psi, z, xy, viewMode})
fullscreen_button = {
  const button = document.querySelector("#mobius-fullscreen-button");
  const explorer = document.querySelector("#mobius-revealed-explorer");
  const controller = new AbortController();

  function updateLabel() {
    const isFullscreen = document.fullscreenElement === explorer;
    button.textContent = isFullscreen ? "×" : "⛶";
    button.setAttribute("aria-label", isFullscreen ? "Exit fullscreen" : "Enter fullscreen");
    button.setAttribute("title", isFullscreen ? "Exit fullscreen" : "Enter fullscreen");
  }

  button.addEventListener("click", async () => {
    if (document.fullscreenElement === explorer) {
      await document.exitFullscreen();
    } else {
      await explorer.requestFullscreen();
    }
    updateLabel();
  }, {signal: controller.signal});

  document.addEventListener("fullscreenchange", updateLabel, {signal: controller.signal});
  updateLabel();
  invalidation.then(() => controller.abort());
  undefined
}

Comments

Möbius transformations are complex functions mapping \(\mathbb{C} \to \mathbb{C}\) that have the form \[T(z) = \frac{az+b}{cz+d}.\] This interactive demo shows how they can be realized as rigid motions of a sphere via stereographic projection. The square shown in the plane is the image of the patch on the sphere. You can fiddle with the sliders to change the position and orientation of the sphere. The patch is then reprojected onto the plane and the result is the image of the original square under a Möbius transformation. The controls

  • The 2D \(x\text{-}y\) slider translates the sphere parallel to the complex plane; the projection shifts together with the sphere.
  • The \(z\) slider translates the sphere up and down; the projections dilates or contracts accordingly.
  • The \(\theta\) slider rotates the sphere around its north-south axis, which is initially the \(z\)-axis.
  • The \(\varphi\) slider rotates the sphere about an axis parallel to the complex plane.
  • The \(\psi\) slider rotates the axis of rotation for \(\varphi\).

More precisely, the three rotation controls are the ZXZ Euler angles \((\psi,\varphi,\theta-\psi)\).

 

Written, owned, hosted, and copyright 2025, Mark McClure