Parameterizing Sphere Linkages

Using iterated suspensions to get nice coordinates on configuration space

Second in a series on spherical configuration spaces of planar linkages, joint work with Aaron Abrams, Dave Bachmann, and Edmund Harriss. The setup is in the first post.

In the previous post we showed that the configuration space MLn\mathcal{M}^n_L of an nn-rod planar chain pinned at both ends — the locus in TnT^n where the rod angles satisfy the closure equation keiθk=L\sum_k e^{i\theta_k} = L — is homeomorphic to the (n2)(n-2)-sphere whenever n2<L<nn - 2 < L < n. The argument was inductive: peeling off the last rod identifies MLn\mathcal{M}^n_L as a topological suspension of Mdn1\mathcal{M}^{n-1}_d at an appropriate sub-base length dd, so iterating from the base case ML2=S0\mathcal{M}^2_L = S^0 gives a tower of n2n - 2 suspensions, Σn2S0=Sn2\Sigma^{n-2} S^0 = S^{n-2}.

What that proof established was the homeomorphism type. What it didn’t give us, at least not directly, was the explicit homeomorphism — a map you could plug into a computer and calculate with. In this post we’ll write one down:

ΨLn   ⁣:  Sn2MLn,\Psi^n_L \;\colon\; S^{n-2} \longrightarrow \mathcal{M}^n_L,

an explicit homeomorphism, for each n2n \geq 2 and every LL in the allowable range.

We work up by example. After the trivial base case n=2n = 2 — just two configurations of the elbow-up/elbow-down kind — we build ΨL3\Psi^3_L from ΨL2\Psi^2_L explicitly, by hand. The first nontrivial step is where the geometric and analytic moves of the construction show themselves most clearly: rescaling, smoothing across the suspension poles, the whole story. Once we see the pattern, we articulate the general “add one rod, get one suspension” recipe. Then we apply that recipe to get ΨL4\Psi^4_L as a parameterization of ML4S2\mathcal{M}^4_L \cong S^2, and gesture at the iteration to higher dimensions.

Each section will follow the same template: build the parameterization in rod angles first — the natural coordinates inherited from the suspension construction — then convert to position coordinates, the locations of the chain’s interior hinges. The position-space form is consistently cleaner: the inverse trig functions that clutter the rod-angle formula collapse into elementary expressions, and smoothness across the suspension poles becomes transparent.

Angle coordinates and position coordinates

There are two natural sets of coordinates for an nn-rod planar chain pinned at 00 and LL:

The two are related by the cumulative sum: pk=pk1+eiθk\mathbf{p}_k = \mathbf{p}_{k-1} + e^{i\theta_k} (taking p0:=0\mathbf{p}_0 := 0), and going back, eiθk=pkpk1e^{i\theta_k} = \mathbf{p}_k - \mathbf{p}_{k-1} — the unit vector from one hinge to the next.

In position coordinates the closure equation has already been folded in: the last position pn=L\mathbf{p}_n = L is fixed by the pinning, so it doesn’t appear among the coordinates at all.

In angle coordinates closure can be used to drop one coordinate too. The first n1n-1 angles determine the position of pn1\mathbf{p}_{n-1}, and for the chain to close, the last rod must be the unique unit segment from pn1\mathbf{p}_{n-1} to LL — so θn=arg(Lpn1)\theta_n = \arg(L - \mathbf{p}_{n-1}) is determined by the others. Dropping it gives an embedding MLnTn1\mathcal{M}^n_L \hookrightarrow T^{n-1} (as mentioned in post 1) that we’ll exploit for visualizations.

ML2S0\mathcal{M}^2_L \cong S^0

For the base case, we’ll think of S0S^0 as the discrete two-point set parameterized by a sign variable

σ{+1,  1}.\sigma \in \{+1,\; -1\}.

The two configurations are the elbow-up and elbow-down isoceles triangles with vertices (0,0)(0, 0), p1\mathbf{p}_1, (L,0)(L, 0), with the equal sides of length 11.

Angle coordinates

The triangle’s two equal base angles are both the elbow half-angle

β(L)  :=  arccos(L/2),\beta(L) \;:=\; \arccos(L/2),

so rod 1 makes angle σβ(L)\sigma\,\beta(L) with the positive xx-axis and rod 2 makes the opposite angle:

  ΨL2(σ)  =  (σβ(L),    σβ(L)).  \boxed{\; \Psi^2_L(\sigma) \;=\; \big(\,\sigma\,\beta(L),\;\; -\sigma\,\beta(L)\,\big). \;}

Closure check. eiσβ+eiσβ=2cosβ(L)=Le^{i\sigma\beta} + e^{-i\sigma\beta} = 2\cos\beta(L) = L ✓ (using cosβ(L)=L/2\cos\beta(L) = L/2 by definition).

Position coordinates

The single interior hinge sits on the unit circle at angle σβ\sigma\beta. Since cosβ=L/2\cos\beta = L/2 and sinβ=4L2/2\sin\beta = \sqrt{4-L^2}/2,

  ΨL2   ⁣:  σ    p1  =  12(L+iσ4L2),σ{+1,1}.  \boxed{\; \Psi^2_L \;\colon\; \sigma \;\longmapsto\; \mathbf{p}_1 \;=\; \tfrac{1}{2}\big(L + i\sigma\sqrt{4 - L^2}\big), \qquad \sigma \in \{+1, -1\}. \;}

ML3S1\mathcal{M}^3_L \cong S^1

We build ΨL3 ⁣:S1ML3\Psi^3_L \colon S^1 \to \mathcal{M}^3_L by hand from the base case Ψd2\Psi^2_d. The strategy comes straight from the suspension proof of last post: project a ML3\mathcal{M}^3_L configuration onto its last rod’s angle, parameterize the fiber over that angle as a sub-config in Md2\mathcal{M}^2_d, and place the result in the right ambient frame.

Angle coordinates

The suspension structure

Fix a target value θ\theta for the third rod’s angle. With this last rod placed, the second-to-last vertex sits at p2=Leiθ\mathbf{p}_2 = L - e^{i\theta}. The first two rods then span from the origin to p2\mathbf{p}_2 — a M2\mathcal{M}^2-style chain at sub-base length

d  :=  Leiθ  =  L22Lcosθ+1.d \;:=\; |L - e^{i\theta}| \;=\; \sqrt{L^2 - 2L\cos\theta + 1}.

For this sub-chain to exist we need d2d \leq 2, which restricts θ\theta to an arc

θ[α,α],α  :=  arccos ⁣L232L.\theta \in [-\alpha,\, \alpha], \qquad \alpha \;:=\; \arccos\!\frac{L^2 - 3}{2L}.

For each interior θ\theta, the sub-chain in its own reference frame — base laid along the positive xx-axis from (0,0)(0,0) to (d,0)(d, 0) — is a configuration of Md2\mathcal{M}^2_d, parameterized by the sheet sign σ{±1}\sigma \in \{\pm 1\} from before:

Ψd2(σ)  =  (σβ(d),    σβ(d)),β(d)  :=  arccos(d/2).\Psi^2_d(\sigma) \;=\; \big(\,\sigma\,\beta(d),\;\; -\sigma\,\beta(d)\,\big), \qquad \beta(d) \;:=\; \arccos(d/2).

To place the sub-chain in the ambient frame (where it should run from the origin to p2=Leiθ\mathbf{p}_2 = L - e^{i\theta} rather than to (d,0)(d, 0)), we rotate by

R  :=  arg ⁣(Leiθ).R \;:=\; \arg\!\big(L - e^{i\theta}\big).

Both frames share the origin, so this is a pure rotation — no translation needed. (This is the geometric payoff of projecting onto the last rod rather than the first.) Rotating each rod-vector by RR adds RR to its angle, so the rotated sub-config has rod-angles (R+σβ,  Rσβ)(R + \sigma\beta,\; R - \sigma\beta).

Stacking all three rods, the parameterization sending (θ,σ)(\theta, \sigma) to a configuration in ML3\mathcal{M}^3_L is

(θ,σ)    (R+σβ(d),    Rσβ(d),    θ),(\theta, \sigma) \;\longmapsto\; \big(\, R + \sigma\,\beta(d),\;\; R - \sigma\,\beta(d),\;\; \theta \,\big),

with d,R,βd, R, \beta defined above.

Closure check. ei(R+σβ)+ei(Rσβ)=eiR(eiσβ+eiσβ)=2cosβeiR=deiRe^{i(R + \sigma\beta)} + e^{i(R - \sigma\beta)} = e^{iR}(e^{i\sigma\beta} + e^{-i\sigma\beta}) = 2\cos\beta\, e^{iR} = d\, e^{iR}, using cosβ=d/2\cos\beta = d/2. And deiR=Leiθd\, e^{iR} = L - e^{i\theta} by definition of RR. So the rod-vectors sum to (Leiθ)+eiθ=L(L - e^{i\theta}) + e^{i\theta} = L. ✓

Suspension coordinates

The natural domain for our parameterization is the suspension itself — ΣS0=[1,1]×S0\Sigma S^0 = [-1, 1] \times S^0, with the four endpoints (±1,±1)(\pm 1, \pm 1) glued in pairs at the two suspension poles s=±1s = \pm 1. This is the same domain regardless of LL. We want a map ΨL3 ⁣:ΣS0ML3\Psi^3_L \colon \Sigma S^0 \to \mathcal{M}^3_L on this fixed domain.

The second factor lines up for free: σ\sigma already lives in S0S^0. The first factor needs a rescaling — currently θ\theta runs over the LL-dependent arc [α,α][-\alpha, \alpha], but we want it to come from [1,1][-1, 1]. The simplest choice does it:

s[1,1],θ  =  αs.s \in [-1, 1], \qquad \theta \;=\; \alpha\, s.

Pulling our parameterization back through this rescaling defines

  ΨL3   ⁣:  ΣS0ML3,ΨL3(s,σ)  =  (R+σβ(d),    Rσβ(d),    αs),  \boxed{\; \begin{aligned} \Psi^3_L \;&\colon\; \Sigma S^0 \to \mathcal{M}^3_L, \\[4pt] \Psi^3_L(s, \sigma) \;&=\; \big(\, R + \sigma\,\beta(d),\;\; R - \sigma\,\beta(d),\;\; \alpha\, s \,\big), \end{aligned} \;}

with θ=αs\theta = \alpha s, d=L22Lcosθ+1d = \sqrt{L^2 - 2L\cos\theta + 1}, R=arg(Leiθ)R = \arg(L - e^{i\theta}), β=arccos(d/2)\beta = \arccos(d/2).

This is a perfectly good homeomorphism from ΣS0\Sigma S^0 to ML3\mathcal{M}^3_L. But the domain isn’t a smooth circle: the sheet sign σ\sigma is a discrete variable, not a smooth coordinate. To get a smooth map from S1S^1 we have to repackage (s,σ)(s, \sigma) in terms of a single circular variable.

Smoothing the parameterization

Introduce a circular variable t[π,π)t \in [-\pi,\, \pi) — the angle on S1={eit}S^1 = \{e^{it}\} — and parameterize the suspension coordinates by

s(t)  :=  sint,σ(t)  :=  sgn(cost).s(t) \;:=\; \sin t, \qquad \sigma(t) \;:=\; \operatorname{sgn}(\cos t).

As tt runs from π-\pi to π\pi:

So tt traces the upper sheet from south pole to north pole, then the lower sheet back, completing the full circle. Composing with the suspension formula gives θ(t)=αsint\theta(t) = \alpha\sin t and a single-variable map ΨL3 ⁣:S1ML3\Psi^3_L \colon S^1 \to \mathcal{M}^3_L,

  ΨL3   ⁣:  t    (R(t)+σ(t)β(t)R(t)σ(t)β(t)θ(t)),t[π,π),α  =  arccos ⁣L232L,θ(t)  =  αsint,σ(t)  =  sgn(cost),d(t)  =  L22Lcosθ(t)+1,R(t)  =  arg ⁣(Leiθ(t)),β(t)  =  arccos(d(t)/2).  \boxed{\; \begin{gathered} \Psi^3_L \;\colon\; t \;\longmapsto\; \begin{pmatrix} R(t) + \sigma(t)\,\beta(t) \\[2pt] R(t) - \sigma(t)\,\beta(t) \\[2pt] \theta(t) \end{pmatrix}, \qquad t \in [-\pi,\, \pi), \\[10pt] \begin{aligned} \alpha \;&=\; \arccos\!\tfrac{L^2 - 3}{2L}, \\ \theta(t) \;&=\; \alpha\sin t, \\ \sigma(t) \;&=\; \operatorname{sgn}(\cos t), \\ d(t) \;&=\; \sqrt{L^2 - 2L\cos\theta(t) + 1}, \\ R(t) \;&=\; \arg\!\big(L - e^{i\theta(t)}\big), \\ \beta(t) \;&=\; \arccos(d(t)/2). \end{aligned} \end{gathered} \;}

Or in code:

function psi3(t, L) {
  const alpha = Math.acos((L*L - 3) / (2*L));
  const theta = alpha * Math.sin(t);
  const sigma = Math.cos(t) >= 0 ? 1 : -1;
  const d     = Math.sqrt(L*L - 2*L*Math.cos(theta) + 1);
  const R     = Math.atan2(-Math.sin(theta), L - Math.cos(theta));
  const beta  = Math.acos(d / 2);
  return [R + sigma * beta, R - sigma * beta, theta];
}

By closure, θ3=θ(t)\theta_3 = \theta(t) is determined by the first two rod angles, so we can drop it and equivalently view ML3\mathcal{M}^3_L as a closed curve in the 2-torus. This lower-dimensional embedding is easier to picture than the full curve in T3T^3 — and the savings will matter even more for the next case (ML4\mathcal{M}^4_L as a sphere in T3T^3 rather than T4T^4).

Position coordinates

To convert the rod-angle formula into hinge positions, sum cumulatively: p1=eiθ1\mathbf{p}_1 = e^{i\theta_1}, p2=eiθ1+eiθ2\mathbf{p}_2 = e^{i\theta_1} + e^{i\theta_2}. The simplifications happen because of two complex-exponential identities — exponentials eat inverse trig functions:

In the rod-angle picture these inverse trig wrappers stay; in the position-space picture they collapse.

p2\mathbf{p}_2. Sum the two halves:

p2  =  eiθ1+eiθ2  =  eiR(eiσβ+eiσβ)  =  2cosβeiR  =  deiR.\mathbf{p}_2 \;=\; e^{i\theta_1} + e^{i\theta_2} \;=\; e^{iR}(e^{i\sigma\beta} + e^{-i\sigma\beta}) \;=\; 2\cos\beta \cdot e^{iR} \;=\; d\,e^{iR}.

Then eiR=(Leiθ)/de^{iR} = (L - e^{i\theta})/d kills the dd:

p2  =  Leiθ.\mathbf{p}_2 \;=\; L - e^{i\theta}.

Geometric reading: p2\mathbf{p}_2 is the right endpoint LL minus the third rod’s vector eiθe^{i\theta} — the chain, end backwards.

p1\mathbf{p}_1. From p1=eiReiσβ\mathbf{p}_1 = e^{iR}\,e^{i\sigma\beta}, multiply the two simplified factors:

p1  =  Leiθdd+iσ4d22  =  p22  +  iσ4p222p2p2.\mathbf{p}_1 \;=\; \frac{L - e^{i\theta}}{d} \cdot \frac{d + i\sigma\sqrt{4 - d^2}}{2} \;=\; \frac{\mathbf{p}_2}{2} \;+\; \frac{i\sigma\sqrt{4 - |\mathbf{p}_2|^2}}{2\,|\mathbf{p}_2|}\,\mathbf{p}_2.

Geometric reading: p1\mathbf{p}_1 is the midpoint of 0p2\overline{0\mathbf{p}_2} plus a perpendicular offset — the elbow of two unit rods spanning a base of length p2=d|\mathbf{p}_2| = d. The factor ip2/p2i\,\mathbf{p}_2/|\mathbf{p}_2| is the unit vector perpendicular to p2\mathbf{p}_2, the offset magnitude is 4p22/2\sqrt{4-|\mathbf{p}_2|^2}/2, and σ\sigma picks the sheet.

Smoothness, transparently

In rod-angle coordinates, smoothness across t=±π/2t = \pm\pi/2 would require chasing the sign jump of σ\sigma through the cusp of β\beta and verifying that they cancel. In position coordinates, every step above is elementary except for σ4p22\sigma\sqrt{4-|\mathbf{p}_2|^2}, and that combines into a single smooth signed amplitude. Define

ν(t)  :=  cost4p2(t)2cos2t  =  cost2L(cosθcosα)cos2t,\nu(t) \;:=\; \cos t \,\sqrt{\frac{4 - |\mathbf{p}_2(t)|^2}{\cos^2 t}} \;=\; \cos t\,\sqrt{\frac{2L(\cos\theta - \cos\alpha)}{\cos^2 t}},

using 4p22=2L(cosθcosα)4 - |\mathbf{p}_2|^2 = 2L(\cos\theta - \cos\alpha) (from the law of cosines and cosα=(L23)/(2L)\cos\alpha = (L^2-3)/(2L)). The ratio under the radical extends by continuity to its limit at cost=0\cos t = 0: a Taylor expansion at t=π/2t = \pi/2 gives 4p22Lαsinαcos2t4 - |\mathbf{p}_2|^2 \sim L\alpha\sin\alpha\,\cos^2 t, so the ratio extends smoothly to Lαsinα>0L\alpha\sin\alpha > 0. Outside the poles ν(t)=σ(t)4p2(t)2\nu(t) = \sigma(t)\sqrt{4 - |\mathbf{p}_2(t)|^2}, by direct computation: costX/cos2t=sgn(cost)X\cos t \cdot \sqrt{X/\cos^2 t} = \mathrm{sgn}(\cos t)\sqrt{X} for X>0X > 0. So ν\nu is smooth everywhere on R\mathbb{R}, and its zeros at t=±π/2t = \pm\pi/2 are linear crossings — exactly what we’d expect for the signed altitude of a triangle whose elbow passes through the base.

The same expression can be rewritten without any apparent singularity at all. Applying the product-to-sum identity to cosθcosα\cos\theta - \cos\alpha and a half-angle substitution gives

ν(t)  =  αLcostsinc ⁣α(1+sint)2sinc ⁣α(1sint)2,sinc(x):=sinxx,\nu(t) \;=\; \alpha\sqrt{L}\,\cos t \,\sqrt{\operatorname{sinc}\!\tfrac{\alpha(1+\sin t)}{2}\,\operatorname{sinc}\!\tfrac{\alpha(1-\sin t)}{2}}, \qquad \operatorname{sinc}(x) := \tfrac{\sin x}{x},

with sinc(0):=1\operatorname{sinc}(0) := 1 by continuity.

A graph of v(t) showing its smoothness over the domain.
A graph of v(t) showing its smoothness over the domain.

Substituting:

  ΨL3   ⁣:  t    (p1p2)  =  (p2  +  iν2ppp)α  =  arccos ⁣L232L,θ(t)  =  αsint,p(t)  =  Leiθ(t),ν(t)  =  cost2L(cosθcosα)cos2t.  \boxed{\; \begin{gathered} \Psi^3_L \;\colon\; t \;\longmapsto\; \begin{pmatrix} \mathbf{p}_1 \\[4pt] \mathbf{p}_2 \end{pmatrix} \;=\; \begin{pmatrix} \dfrac{p}{2} \;+\; \dfrac{i\,\nu}{2\,|p|}\,p \\[10pt] p \end{pmatrix} \\[10pt] \begin{aligned} \alpha \;&=\; \arccos\!\tfrac{L^2 - 3}{2L}, \\ \theta(t) \;&=\; \alpha\sin t, \\ p(t) \;&=\; L - e^{i\theta(t)}, \\ \nu(t) \;&=\; \cos t\,\sqrt{\dfrac{2L(\cos\theta - \cos\alpha)}{\cos^2 t}}. \end{aligned} \end{gathered} \;}

Or in code:

function psi3Position(t, L) {
  const alpha = Math.acos((L*L - 3) / (2*L));
  const theta = alpha * Math.sin(t);
  const c     = Math.cos(t);

  // p = L - e^{i theta}
  const p_re  = L - Math.cos(theta);
  const p_im  =   - Math.sin(theta);
  const p_abs = Math.hypot(p_re, p_im);

  // nu(t): smooth signed amplitude. Numerator and denominator both vanish
  // quadratically at cos t = 0; the ratio extends to L*alpha*sin(alpha).
  const num = 2 * L * (Math.cos(theta) - (L*L - 3) / (2*L));
  const nu  = Math.abs(c) < 1e-6
            ? Math.sign(c || 1) * Math.sqrt(L * alpha * Math.sin(alpha))
            : c * Math.sqrt(num / (c * c));

  // p1 = p/2 + (i nu / (2|p|)) * p
  const k = nu / (2 * p_abs);
  return {
    p1: [p_re / 2 - k * p_im, p_im / 2 + k * p_re],
    p2: [p_re, p_im],
  };
}

Click on the circle to drag the configuration around yourself!

The general step

What we just did for ΨL3\Psi^3_L generalizes. The geometric structure of the construction — project on the last rod’s angle, fix the sub-base length and orientation, parameterize the fiber by the inner config space — is the same at every level of the iteration. Let’s articulate it as a recipe.

Angle coordinates

Suppose, inductively, that we have a smooth parameterization

Ψdn ⁣:Sn2Mdn\Psi^n_d \colon S^{n-2} \longrightarrow \mathcal{M}^n_d

in angle coordinates, for every dd in the corresponding allowable range n2<d<nn - 2 < d < n. We want to build ΨLn+1 ⁣:Sn1MLn+1\Psi^{n+1}_L \colon S^{n-1} \to \mathcal{M}^{n+1}_L from Ψn\Psi^n.

Coordinate the parameterizing sphere Sn1S^{n-1} by a latitude ϕ[π/2,π/2]\phi \in [-\pi/2, \pi/2] and a fiber point pSn2p \in S^{n-2} (the inner spherical coordinates), with the fiber collapsing at the two poles ϕ=±π/2\phi = \pm\pi/2. We’ll bake the smooth sin\sin-rescaling directly into the recipe — exactly analogous to what we did for ΨL3\Psi^3_L — so that the suspension axis is from the start an angle, going pole-to-pole through the equator.

The same three helper functions show up. The half-width of the admissible arc for the last rod, when the sub-chain has nn rods that need to span up to distance nn, is

α(n,L)  :=  arccos ⁣L2n2+12L.\alpha(n, L) \;:=\; \arccos\!\frac{L^2 - n^2 + 1}{2L}.

The sub-base length and sub-frame rotation as functions of the last-rod angle θ\theta are

d(L,θ)  :=  L22Lcosθ+1,R(L,θ)  :=  arg ⁣(Leiθ).d(L, \theta) \;:=\; \sqrt{L^2 - 2L\cos\theta + 1}, \qquad R(L, \theta) \;:=\; \arg\!\big(L - e^{i\theta}\big).

Set θ=αsinϕ\theta = \alpha\sin\phi as we did for the circle: the standard latitude rescaling that takes the equator ϕ=0\phi = 0 to θ=0\theta = 0 and the poles ϕ=±π/2\phi = \pm\pi/2 to θ=±α\theta = \pm\alpha. Then for each (ϕ,p)Sn1(\phi, p) \in S^{n-1}, the recipe gives

  ΨLn+1(ϕ,p)  =  (R+Ψdn(p),    αsinϕ),  \boxed{\; \Psi^{n+1}_L(\phi, p) \;=\; \big(\, R + \Psi^n_d(p),\;\; \alpha\sin\phi \,\big), \;}

where α=α(n,L)\alpha = \alpha(n, L), θ=αsinϕ\theta = \alpha\sin\phi, d=d(L,θ)d = d(L, \theta), R=R(L,θ)R = R(L, \theta), and R+(θ1,,θn):=(R+θ1,,R+θn)R + (\theta_1, \ldots, \theta_n) := (R + \theta_1, \ldots, R + \theta_n) is componentwise scalar addition.

Position coordinates

Suppose inductively that we have Ψdn\Psi^n_d in position coordinates: Ψdn(p)\Psi^n_d(p) outputs a tuple of n1n - 1 interior hinges in C\mathbb{C} for a chain pinned at 00 and dd on the real axis (its “sub-frame”).

Coordinate Sn1S^{n-1} the same way as before, with the same θ=αsinϕ\theta = \alpha\sin\phi. The outermost interior hinge of the new chain is determined by θ\theta alone — closure forces the last rod to be eiθe^{i\theta}, so

pn  =  Leiθ,\mathbf{p}_n \;=\; L - e^{i\theta},

the same “endpoint minus last rod” identity that gave us p2\mathbf{p}_2 in the circle case, now at the outer level. Its modulus pn|\mathbf{p}_n| is the sub-base length dd, and its direction p^n:=pn/d\hat{\mathbf{p}}_n := \mathbf{p}_n / d is the rotation that places the sub-frame in the ambient one.

The first n1n - 1 interior hinges come from the inner sub-chain. Ψdn(p)\Psi^n_d(p) produces them in the sub-frame; componentwise multiplication by p^n\hat{\mathbf{p}}_n rotates them into the ambient frame. So:

  ΨLn+1(ϕ,p)  =  (p^nΨdn(p),    pn),  \boxed{\; \Psi^{n+1}_L(\phi, p) \;=\; \big(\, \hat{\mathbf{p}}_n \cdot \Psi^n_d(p), \;\; \mathbf{p}_n \,\big), \;}

with pn=Leiθ\mathbf{p}_n = L - e^{i\theta} and p^n(z1,,zn1):=(p^nz1,,p^nzn1)\hat{\mathbf{p}}_n \cdot (z_1, \ldots, z_{n-1}) := (\hat{\mathbf{p}}_n z_1, \ldots, \hat{\mathbf{p}}_n z_{n-1}) being componentwise complex multiplication.

Geometric reading: append one new outer hinge, rotate the rest into place. The whole step is a complex subtraction and a complex multiplication — no inverse trig at the recursion level. (p^n\hat{\mathbf{p}}_n is the same rotation that the angle picture writes as eiRe^{iR}, just packaged as a unit complex number rather than a scalar angle.)

ML4S2\mathcal{M}^4_L \cong S^2

We’re now ready to apply the general step with n=3n = 3 to build the parameterization of the 2-sphere. Coordinate S2S^2 by latitude ϕ[π/2,π/2]\phi \in [-\pi/2, \pi/2] and longitude tS1t \in S^1 — in the recipe’s notation, ϕ\phi is the suspension parameter and tt is the inner fiber point, which we feed directly into Ψd3\Psi^3_d from §3. As with standard spherical coordinates, this chart has the usual singularities at the poles ϕ=±π/2\phi = \pm\pi/2, where the longitude tt becomes meaningless.

Angle coordinates

The angle-version recipe gives

ΨL4(ϕ,t)  =  (R+Ψd3(t),    αsinϕ),\Psi^4_L(\phi, t) \;=\; \big(\, R + \Psi^3_d(t), \;\; \alpha\sin\phi \,\big),

where the outer-level helpers are functions of ϕ\phi alone and the inner Ψd3(t)\Psi^3_d(t) is the §3 formula evaluated at base length dd, with its own inner helpers as functions of ϕ\phi and tt. Stacking the four rod angles and laying out all helpers in one place:

  ΨL4   ⁣:  (ϕ,t)    (R+Rin+σβinR+RinσβinR+θinαsinϕ)α  =  arccos ⁣L282L,θ(ϕ)  =  αsinϕ,d(ϕ)  =  L22Lcosθ+1,R(ϕ)  =  arg ⁣(Leiθ),σ(t)  =  sgn(cost),αin(ϕ)  =  arccos ⁣d232d,θin(ϕ,t)  =  αinsint,din(ϕ,t)  =  d22dcosθin+1,Rin(ϕ,t)  =  arg ⁣(deiθin),βin(ϕ,t)  =  arccos(din/2).  \boxed{\; \begin{gathered} \Psi^4_L \;\colon\; (\phi, t) \;\longmapsto\; \begin{pmatrix} R + R_\text{in} + \sigma\,\beta_\text{in} \\[2pt] R + R_\text{in} - \sigma\,\beta_\text{in} \\[2pt] R + \theta_\text{in} \\[2pt] \alpha\sin\phi \end{pmatrix} \\[10pt] \begin{aligned} \alpha \;&=\; \arccos\!\tfrac{L^2 - 8}{2L}, \\ \theta(\phi) \;&=\; \alpha\sin\phi, \\ d(\phi) \;&=\; \sqrt{L^2 - 2L\cos\theta + 1}, \\ R(\phi) \;&=\; \arg\!\big(L - e^{i\theta}\big), \\ \sigma(t) \;&=\; \operatorname{sgn}(\cos t), \\ \alpha_\text{in}(\phi) \;&=\; \arccos\!\tfrac{d^2 - 3}{2d}, \\ \theta_\text{in}(\phi, t) \;&=\; \alpha_\text{in}\sin t, \\ d_\text{in}(\phi, t) \;&=\; \sqrt{d^2 - 2d\cos\theta_\text{in} + 1}, \\ R_\text{in}(\phi, t) \;&=\; \arg\!\big(d - e^{i\theta_\text{in}}\big), \\ \beta_\text{in}(\phi, t) \;&=\; \arccos(d_\text{in}/2). \end{aligned} \end{gathered} \;}

Or in code:

function psi4(phi, t, L) {
  // Outer level
  const alpha = Math.acos((L*L - 8) / (2*L));
  const theta = alpha * Math.sin(phi);
  const d     = Math.sqrt(L*L - 2*L*Math.cos(theta) + 1);
  const R     = Math.atan2(-Math.sin(theta), L - Math.cos(theta));

  // Inner Psi^3_d(t)
  const alpha_in = Math.acos((d*d - 3) / (2*d));
  const theta_in = alpha_in * Math.sin(t);
  const sigma    = Math.cos(t) >= 0 ? 1 : -1;
  const d_in     = Math.sqrt(d*d - 2*d*Math.cos(theta_in) + 1);
  const R_in     = Math.atan2(-Math.sin(theta_in), d - Math.cos(theta_in));
  const beta_in  = Math.acos(d_in / 2);

  return [
    R + R_in + sigma * beta_in,
    R + R_in - sigma * beta_in,
    R + theta_in,
    theta
  ];
}

By closure we can drop the last rod angle and view ML4\mathcal{M}^4_L as a 2-sphere embedded in T3T^3 rather than T4T^4. The savings really pay off here: T3T^3 as a periodic cube is drawable; T4T^4 is not.

The animation above illustrates this parameterization with the domain S2S^2 on the left and its image T3\subset T^3 on the right. Click and drag the point on the domain to explore the parameterization.

Position coordinates

The position-version recipe gives

ΨL4(ϕ,t)  =  (p^3Ψd3(t),    p3),\Psi^4_L(\phi, t) \;=\; \big(\, \hat{\mathbf{p}}_3 \cdot \Psi^3_d(t), \;\; \mathbf{p}_3 \,\big),

with p3=Leiθ\mathbf{p}_3 = L - e^{i\theta} the new outermost interior hinge and p^3=p3/p3\hat{\mathbf{p}}_3 = \mathbf{p}_3 / |\mathbf{p}_3| the rotation onto the ambient frame. The inner Ψd3(t)\Psi^3_d(t) from §3 produces the two interior hinges of an Md3\mathcal{M}^3_d chain in its sub-frame:

p2  =  deiθin,p1  =  p22  +  iνin2p2p2,\mathbf{p}_2^\circ \;=\; d - e^{i\theta_\text{in}}, \qquad \mathbf{p}_1^\circ \;=\; \frac{\mathbf{p}_2^\circ}{2} \;+\; \frac{i\,\nu_\text{in}}{2\,|\mathbf{p}_2^\circ|}\,\mathbf{p}_2^\circ,

with inner helpers

αin  =  arccos ⁣d232d,θin  =  αinsint,νin  =  cost2d(cosθincosαin)cos2t.\alpha_\text{in} \;=\; \arccos\!\tfrac{d^2 - 3}{2d}, \quad \theta_\text{in} \;=\; \alpha_\text{in}\sin t, \quad \nu_\text{in} \;=\; \cos t\,\sqrt{\dfrac{2d(\cos\theta_\text{in} - \cos\alpha_\text{in})}{\cos^2 t}}.

Multiplying by p^3\hat{\mathbf{p}}_3 rotates these into the ambient frame. The middle hinge inherits the recurring “endpoint minus last rod” identity, one level in:

p2  =  p^3p2  =  p^3(deiθin)  =  p3    p^3eiθin,\mathbf{p}_2 \;=\; \hat{\mathbf{p}}_3 \cdot \mathbf{p}_2^\circ \;=\; \hat{\mathbf{p}}_3\,(d - e^{i\theta_\text{in}}) \;=\; \mathbf{p}_3 \;-\; \hat{\mathbf{p}}_3\,e^{i\theta_\text{in}},

using p^3d=p3\hat{\mathbf{p}}_3 \cdot d = \mathbf{p}_3. Same shape as p3=Leiθ\mathbf{p}_3 = L - e^{i\theta}, but with the ambient-frame “endpoint” p3\mathbf{p}_3 taking the role of LL and the rotated unit vector p^3eiθin\hat{\mathbf{p}}_3\,e^{i\theta_\text{in}} taking the role of the last rod eiθe^{i\theta}. The innermost hinge inherits the elbow formula:

p1  =  p^3p1  =  p22  +  iνin2p2p2,\mathbf{p}_1 \;=\; \hat{\mathbf{p}}_3 \cdot \mathbf{p}_1^\circ \;=\; \frac{\mathbf{p}_2}{2} \;+\; \frac{i\,\nu_\text{in}}{2\,|\mathbf{p}_2|}\,\mathbf{p}_2,

since rotation preserves both the elbow’s relative geometry and the modulus p2=p2=din|\mathbf{p}_2| = |\mathbf{p}_2^\circ| = d_\text{in}. Boxed:

  ΨL4   ⁣:  (ϕ,t)    (p1p2p3)  =  (p22  +  iνin2p2p2p3    p^3eiθinL    eiθ)α  =  arccos ⁣L282L,θ(ϕ)  =  αsinϕ,p3(ϕ)  =  Leiθ,p^3  =  p3/p3,αin(ϕ)  =  arccos ⁣p3232p3,θin(ϕ,t)  =  αinsint,νin(ϕ,t)  =  cost2p3(cosθincosαin)cos2t.  \boxed{\; \begin{gathered} \Psi^4_L \;\colon\; (\phi, t) \;\longmapsto\; \begin{pmatrix} \mathbf{p}_1 \\[4pt] \mathbf{p}_2 \\[4pt] \mathbf{p}_3 \end{pmatrix} \;=\; \begin{pmatrix} \dfrac{\mathbf{p}_2}{2} \;+\; \dfrac{i\,\nu_\text{in}}{2\,|\mathbf{p}_2|}\,\mathbf{p}_2 \\[10pt] \mathbf{p}_3 \;-\; \hat{\mathbf{p}}_3\,e^{i\theta_\text{in}} \\[6pt] L \;-\; e^{i\theta} \end{pmatrix} \\[10pt] \begin{aligned} \alpha \;&=\; \arccos\!\tfrac{L^2 - 8}{2L}, \\ \theta(\phi) \;&=\; \alpha\sin\phi, \\ \mathbf{p}_3(\phi) \;&=\; L - e^{i\theta}, \\ \hat{\mathbf{p}}_3 \;&=\; \mathbf{p}_3 / |\mathbf{p}_3|, \\ \alpha_\text{in}(\phi) \;&=\; \arccos\!\tfrac{|\mathbf{p}_3|^2 - 3}{2\,|\mathbf{p}_3|}, \\ \theta_\text{in}(\phi, t) \;&=\; \alpha_\text{in}\sin t, \\ \nu_\text{in}(\phi, t) \;&=\; \cos t\,\sqrt{\dfrac{2\,|\mathbf{p}_3|\,(\cos\theta_\text{in} - \cos\alpha_\text{in})}{\cos^2 t}}. \end{aligned} \end{gathered} \;}

The recursion peels rods off from the outside in: each level adds an outer hinge of the form (previous level’s “endpoint”) - (rotated unit vector), and the innermost level closes with the elbow formula.

In code:

function psi4Position(phi, t, L) {
  // Outer level
  const alpha = Math.acos((L*L - 8) / (2*L));
  const theta = alpha * Math.sin(phi);

  // p3 = L - e^{i theta}
  const p3_re = L - Math.cos(theta);
  const p3_im =   - Math.sin(theta);
  const d     = Math.hypot(p3_re, p3_im);
  const p3_hat_re = p3_re / d;
  const p3_hat_im = p3_im / d;

  // Inner level (helpers depend on d)
  const c        = Math.cos(t);
  const alpha_in = Math.acos((d*d - 3) / (2*d));
  const theta_in = alpha_in * Math.sin(t);

  // nu_in: smooth signed amplitude (apparent 0/0 at cos t = 0 is removable)
  const num   = 2 * d * (Math.cos(theta_in) - (d*d - 3) / (2*d));
  const nu_in = Math.abs(c) < 1e-6
              ? Math.sign(c || 1) * Math.sqrt(d * alpha_in * Math.sin(alpha_in))
              : c * Math.sqrt(num / (c * c));

  // p2 = p3 - p3_hat * e^{i theta_in}  (complex multiplication then subtract)
  const e_re   = Math.cos(theta_in);
  const e_im   = Math.sin(theta_in);
  const rot_re = p3_hat_re * e_re - p3_hat_im * e_im;
  const rot_im = p3_hat_re * e_im + p3_hat_im * e_re;
  const p2_re  = p3_re - rot_re;
  const p2_im  = p3_im - rot_im;
  const p2_abs = Math.hypot(p2_re, p2_im);

  // p1 = p2/2 + (i nu_in / (2 |p2|)) * p2  (elbow formula in ambient frame)
  const k     = nu_in / (2 * p2_abs);
  const p1_re = p2_re / 2 - k * p2_im;
  const p1_im = p2_im / 2 + k * p2_re;

  return {
    p1: [p1_re, p1_im],
    p2: [p2_re, p2_im],
    p3: [p3_re, p3_im],
  };
}

The animation below shows this map, directly from S2S^2 to the linkage itself. Click and drag the point on the 2-sphere to explore the configuration space.

← All posts