Last updated: 2026-09-27

M
Masters level

Sweeping Shapes: Discs, Cones, and Tori from a Rotor

12.1 A Shape Times a Circle FoundationalKnowledge that endures for decades — core principles

Chapter 9 gave us blades to describe shapes and rotors to move them. A rotor moves a shape through an angle. Let that angle run through a full turn and the shape leaves a trail, which is a new shape one dimension higher. Sweep a line segment about an axis and the trail is a disc. Sweep a circle about an axis, keeping it clear of the axis, and the trail is a torus.

This chapter turns that observation into a recipe. One rotor and a handful of generating shapes produce the disc, the cylinder, the cone, the hyperboloid, the sphere and the torus. We write the result as shape × circle. The × means sweep, and the geometric product does its work inside the rotor. The name is ours. The surfaces are the classical surfaces of revolution, and the rotor form of the sweep is the outer-morphism rule of §10.6 applied across a range of angles[1][2]. cf. planar rotors for arcs

12.2 The Sweep Recipe FoundationalKnowledge that endures for decades — core principles

Three choices define a sweep.

  • 1

    Pick a generator \(X\): a point, a segment, a line or a circle. Anything a rotor can act on will do, and by §10.6 that includes every grade.

  • 2

    Pick a plane of rotation, a unit bivector \(B\). Its dual is the axis. For a turn about \(z\) we use \(B=\mathbf{e}_{12}\).

  • 3

    Sweep. Build the rotor \(R(\theta)=\cos\tfrac{\theta}{2}-\sin\tfrac{\theta}{2}\,B\) and let the angle run: \(S(\theta)=R(\theta)\,X\,\widetilde{R}(\theta)\) for \(0\le\theta<2\pi\). The union of all the copies is the swept shape.

Each point of the generator that is off the axis traces a circle, so a generator of dimension \(k\) sweeps out a shape of dimension \(k+1\). Points on the axis stay where they are.

!

What the sandwich leaves alone. A turn about \(z\) changes a point's angle around the axis and nothing else. Its height \(z\) and its distance from the axis \(\rho=\sqrt{x^2+y^2}\) both survive. So whatever relation between \(\rho\) and \(z\) holds along the generator holds over the whole swept surface. Writing that relation down gives the implicit equation of the surface almost for free, and it gives us a test for every construction below.cylindrical coords: rho and z define the surface profile

GeneratorSwept about \(z\)Result
A point off the axisfull turna circle
A segment from the axis, perpendicular to itfull turna disc (an annulus if it starts away from the axis)
A line through the axis, perpendicular to ithalf turna plane
A segment parallel to the axisfull turna cylinder
A segment through the axis, tiltedfull turna cone
A line that neither meets nor is parallel to the axisfull turna hyperboloid of one sheet
A circle centred on the axis, in a plane that contains ithalf turna sphere
A circle in a plane that contains the axis, clear of itfull turna torus

12.3 A Disc: Line × Circle FoundationalKnowledge that endures for decades — core principles

Start with the simplest sweep. The generator is the segment \(u\,\mathbf{e}_1\) for \(0\le u\le\rho\), and the plane of rotation is \(\mathbf{e}_{12}\).

  • 1

    A single point of the segment: \(u\,\mathbf{e}_1\). Section 10.6 already computed the sandwich on \(\mathbf{e}_1\): \(R(\theta)\,\mathbf{e}_1\,\widetilde{R}(\theta)=\cos\theta\,\mathbf{e}_1+\sin\theta\,\mathbf{e}_2\).

  • 2

    Scale by \(u\). The swept point is \(S(u,\theta)=u\,(\cos\theta\,\mathbf{e}_1+\sin\theta\,\mathbf{e}_2)\).

  • 3

    Read off the shape. Every point has \(z=0\) and \(\rho=u\le\rho_{\max}\), so the sweep fills the disc \(x^2+y^2\le\rho_{\max}^2\) in the plane \(z=0\).

  • 4

    Check the area. The ring at radius \(u\) has circumference \(2\pi u\), so the area is \(\int_0^{\rho}2\pi u\,du=\pi\rho^2\). The factor \(u\) is why the copies in Fig. 12.1 crowd toward the centre.

A disc as a swept line segmentA segment from the origin along the x axis is rotated about the z axis in 30 degree steps; its copies fill the disc.z axis; the rotor uses B = e12the segment u e1
Fig. 12.1. A disc as line × circle. The segment \(u\,\mathbf{e}_1\) (bold) is turned about the \(z\) axis in 30° steps.

Start the segment at \(u_0>0\) and the same sweep gives an annulus of area \(\pi(\rho^2-u_0^2)\). Let \(u\) range over the whole line through the axis and a half turn is enough to cover the plane. half a turn is enough: the line runs both ways

12.4 One Rotor, Three Lines FoundationalKnowledge that endures for decades — core principles

Keep the rotor and change the generator. Three straight lines give three different surfaces, and the tip in 12.2 turns each into a one-line derivation.

SurfaceGenerator\(\rho\) against \(z\) on the generatorImplicit equation
Cylinder\(a\,\mathbf{e}_1+t\,\mathbf{e}_3\)\(\rho=a\)\(x^2+y^2=a^2\)
Cone\(t\,(\sin\alpha\,\mathbf{e}_1+\cos\alpha\,\mathbf{e}_3)\)\(\rho=z\tan\alpha\)\(x^2+y^2=z^2\tan^2\alpha\)
Hyperboloid\(a\,\mathbf{e}_1+t\,(\sin\gamma\,\mathbf{e}_2+\cos\gamma\,\mathbf{e}_3)\)\(\rho^2=a^2+z^2\tan^2\gamma\)\(x^2+y^2=a^2+z^2\tan^2\gamma\)

The hyperboloid row is the least obvious, so we work it through. The generator point at parameter \(t\) is \((a,\ t\sin\gamma,\ t\cos\gamma)\). Its height is \(z=t\cos\gamma\) and its squared distance from the axis is \(\rho^2=a^2+t^2\sin^2\gamma\). Substituting \(t=z/\cos\gamma\) gives \(\rho^2=a^2+z^2\tan^2\gamma\). The waist, where \(z=0\), has radius \(a\).

Three surfaces from one rotor and three linesThe same rotation about the vertical axis sweeps a vertical line into a cylinder, a slanted line through the axis into a cone, and a skew line into a hyperboloid of one sheet.Cylinder: line parallel to the axisCone: line through the axisHyperboloid: skew line
Fig. 12.2. The same rotation about the vertical axis applied to three different lines. The bold line is the generator.

The hyperboloid curves, and it is built entirely from straight lines: every copy of the generator lies on the surface. A skew line gives a doubly curved surface with no bending in it.

12.5 A Torus: Circle × Circle FoundationalKnowledge that endures for decades — core principles

Now sweep a circle. The torus needs two rotors, one for each circle, and the order in which they act matters. The small circle is built first, and the sweep then acts on it.

  • 1

    The small circle. Take the point \(r\,\mathbf{e}_1\) and turn it by an angle \(\varphi\) in the \(\mathbf{e}_{13}\) plane, with \(R_\varphi=\cos\tfrac{\varphi}{2}-\sin\tfrac{\varphi}{2}\,\mathbf{e}_{13}\). By the same calculation as 12.3 with the index 2 replaced by 3, this sends \(\mathbf{e}_1\) to \(\cos\varphi\,\mathbf{e}_1+\sin\varphi\,\mathbf{e}_3\). The circle's centre sits at distance \(R\) from the \(z\) axis, so we shift by \(R\,\mathbf{e}_1\): \[ q(\varphi)=R\,\mathbf{e}_1+R_\varphi\,(r\,\mathbf{e}_1)\,\widetilde{R}_\varphi=(R+r\cos\varphi)\,\mathbf{e}_1+r\sin\varphi\,\mathbf{e}_3. \] The shift is plain vector addition in this algebra. It is the offset-axis rotation of §11.7, where PGA writes the same thing as a translator sandwich around the rotor.

  • 2

    The sweep. Turn the whole small circle about \(z\) with \(R_\theta=\cos\tfrac{\theta}{2}-\sin\tfrac{\theta}{2}\,\mathbf{e}_{12}\): \[ T(\theta,\varphi)=R_\theta\,q(\varphi)\,\widetilde{R}_\theta=\big((R+r\cos\varphi)\cos\theta,\ (R+r\cos\varphi)\sin\theta,\ r\sin\varphi\big). \] Rotors act from the inside out, so \(R_\varphi\) acts first and \(R_\theta\) second.

  • 3

    Check it. On the surface, \(\rho=R+r\cos\varphi\) and \(z=r\sin\varphi\), so \((\rho-R)^2+z^2=r^2\). That is a circle of radius \(r\) in the \((\rho,z)\) half-plane, which is the tip of 12.2 at work. The implicit equation is \[ \big(\sqrt{x^2+y^2}-R\big)^2+z^2=r^2. \]

  • 4

    Measure it. The area element is \(r\,(R+r\cos\varphi)\,d\varphi\,d\theta\). Integrating over both full turns gives the surface area \(4\pi^2Rr\). The enclosed volume is \(2\pi^2Rr^2\): the small disc's area \(\pi r^2\) times the length \(2\pi R\) of the path its centre travels (Pappus's centroid theorem).

A torus as circle times circleA small circle in the xz plane, centred three units from the z axis, is rotated about the z axis. The copies of the small circle and the circles traced by its points form the torus.small circle, angle φswept about z, angle θ
Fig. 12.3. A torus as circle × circle. The small circle (bold) is swept about the \(z\) axis; the circles traced by its points give the other family of curves.

The same formula covers three shapes. With \(r<R\) we get the familiar ring torus. At \(r=R\) the hole closes to a point on the axis (a horn torus), and for \(r>R\) the surface crosses itself (a spindle torus). Each point of the surface has two angles, \(\theta\) and \(\varphi\), and the two circles are independent of each other, which is why the torus is the product of two circles in the topologist's sense as well.

12.6 A Sphere from a Half Turn FoundationalKnowledge that endures for decades — core principles

Sweep the circle of radius \(\rho\) centred at the origin in the \(\mathbf{e}_{13}\) plane, \((\rho\sin\varphi,\ 0,\ \rho\cos\varphi)\), about \(z\). The sweep gives \((\rho\sin\varphi\cos\theta,\ \rho\sin\varphi\sin\theta,\ \rho\cos\varphi)\), which satisfies \(x^2+y^2+z^2=\rho^2\).

A full turn covers the sphere twice, because the circle is symmetric about the axis: the point at \((\varphi,\theta)\) and the point at \((2\pi-\varphi,\ \theta+\pi)\) coincide. A half turn, \(0\le\theta<\pi\), covers it exactly once. Sweeping a semicircle through a full turn gives the same sphere and the same area, \(4\pi\rho^2\).

!

Where the recipe stops. A sweep about one axis makes surfaces with rotational symmetry about it. A general three-axis ellipsoid needs a scaling, which no rotor provides. A helicoid needs a screw motor that adds a translation to the rotation (§11.8). The recipe itself carries over: pick a generator, pick a one-parameter family of motions, and take the union.projective motors add translation to rotation

12.7 Try It: The Sweeps in ganja.js

The constructions above run as they stand in ganja.js[3] in its plain 3D Euclidean algebra. Press Run and the page fetches the library from the jsDelivr CDN and executes the code below in your browser. The source is editable in place: change \(R\), \(r\), or an angle and run it again.

ganja.js uses the same rotor as this chapter, \(\cos\tfrac{\theta}{2}-\sin\tfrac{\theta}{2}\,\mathbf{e}_{12}\), so no sign adjustments are needed. Literals such as 1e12 are algebraic blades, not numbers, because ganja.js rewrites the code inside the function you pass to Algebra.

// Sweeping shapes with rotors, in ganja.js (Euclidean 3D algebra).
Algebra(3, () => {
  const v     = (x, y, z) => x*1e1 + y*1e2 + z*1e3;
  const xyz   = P => [P.e1, P.e2, P.e3].map(c => +c.toFixed(4));
  const deg   = d => d * Math.PI / 180;
  // exp(-theta B / 2) for a unit bivector B: the rotor of Chapter 9.
  const rotor = (th, B) => Math.cos(th/2) - Math.sin(th/2)*B;
  const apply = (R, X) => R * X * ~R;                        // the sandwich product
  const spin  = th => rotor(th, 1e12);                       // turn about the z axis

  // 1. Disc: sweep the segment u e1 (0 <= u <= 2) about z.
  console.log("rim, 90 deg:", xyz(apply(spin(deg(90)), v(2, 0, 0))));            // expect [0, 2, 0]
  console.log("u = 1, 210 deg:", xyz(apply(spin(deg(210)), v(1, 0, 0))));        // expect [-0.866, -0.5, 0]

  // Largest deviation from an implicit equation over a grid of (t, theta) samples.
  const worst = (gen, implicit, ts) => {
    let m = 0;
    for (const t of ts) for (let k = 0; k < 12; k++) {
      const P = apply(spin(deg(30 * k)), gen(t));
      m = Math.max(m, Math.abs(implicit(P.e1, P.e2, P.e3)));
    }
    return +m.toExponential(2);
  };

  // 2. Cylinder, cone and hyperboloid: sweep three different lines about z.
  const a = 1.5, alpha = 0.6, gamma = 0.7, ts = [-2, -1, 0, 1, 2];
  console.log("cylinder:", worst(t => v(a, 0, t), (x, y, z) => Math.hypot(x, y) - a, ts));
  console.log("cone:", worst(t => v(t*Math.sin(alpha), 0, t*Math.cos(alpha)), (x, y, z) => Math.hypot(x, y) - Math.abs(z)*Math.tan(alpha), ts));
  console.log("hyperboloid:", worst(t => v(a, t*Math.sin(gamma), t*Math.cos(gamma)), (x, y, z) => x*x + y*y - a*a - z*z*Math.tan(gamma)**2, ts));

  // 3. Torus: circle x circle. The small circle is a rotor orbit about the axis through (3,0,0) parallel to y;
  //    the big circle is the sweep about z.
  const R = 3, r = 1;
  const tube  = ph => v(R, 0, 0) + apply(rotor(ph, 1e13), v(r, 0, 0));
  const torus = (th, ph) => apply(spin(th), tube(ph));
  console.log("theta 90, phi 0:", xyz(torus(deg(90), 0)));                          // expect [0, 4, 0]
  console.log("theta 90, phi 90:", xyz(torus(deg(90), deg(90))));                   // expect [0, 3, 1]
  let m = 0;
  for (let i = 0; i < 12; i++) for (let j = 0; j < 12; j++) {
    const P = torus(deg(30*i), deg(30*j));
    m = Math.max(m, Math.abs((Math.hypot(P.e1, P.e2) - R)**2 + P.e3**2 - r*r));
  }
  console.log("torus:", +m.toExponential(2));                                       // ~1e-6 (32-bit floats)
});

The output should show the rim point at 90° landing on \((0,2,0)\) and the halfway point at 210° on \((-0.866,-0.5,0)\). The torus points at \(\theta=90^\circ\) should be \((0,4,0)\) for \(\varphi=0\) and \((0,3,1)\) for \(\varphi=90^\circ\). The four residuals report the largest deviation from each implicit equation over a grid of sample points. They come out near \(10^{-7}\) and not exactly zero, because ganja.js stores coefficients in 32-bit floats.

12.8 Testing a Sweep Applied / MethodologicalKnowledge with a 5–10 year half-life — stable practice

A sweep gives us three checks that need no reference implementation. They suit the habits of the testing chapter.

  • Invariants. Every swept point keeps its generator point's height and distance from the axis. Assert both for a grid of angles.
  • Implicit residual. Substitute swept points into the surface's equation. Any residual larger than the arithmetic's rounding error points to a wrong rotor, a wrong plane, or a wrong order of rotors.
  • Area and volume. Sum the area element over a grid and compare with the closed form.

The Python below runs the residual and area checks for the torus, using rotation matrices for the same rotations the rotors perform. With \(R=3\), \(r=1\) and an 800 by 800 midpoint grid, the numerical area agrees with \(4\pi^2Rr=118.4353\) to about nine digits.

import numpy as np

R, r, n = 3.0, 1.0, 800
mid = lambda k: (np.arange(k) + 0.5) * 2 * np.pi / k
ph, th = np.meshgrid(mid(n), mid(n), indexing="ij")

def torus(ph, th):
    rho = R + r * np.cos(ph)               # small circle: (R + r cos phi, r sin phi)
    return np.array([rho * np.cos(th),      # sweep about z by theta
                     rho * np.sin(th),
                     r * np.sin(ph) + 0 * th])

P = torus(ph, th)
residual = (np.hypot(P[0], P[1]) - R) ** 2 + P[2] ** 2 - r ** 2
print("max residual:", np.abs(residual).max())          # ~1e-15

h = 1e-6                                                  # tangent vectors by central differences
d_ph = (torus(ph + h, th) - torus(ph - h, th)) / (2 * h)
d_th = (torus(ph, th + h) - torus(ph, th - h)) / (2 * h)
area = np.linalg.norm(np.cross(d_ph, d_th, axis=0), axis=0).sum() * (2 * np.pi / n) ** 2
print("area:", area, " expected:", 4 * np.pi ** 2 * R * r)

12.9 Key Terms

  • Generator. The shape that is swept: a point, segment, line or circle.
  • Sweep. The union of the copies \(R(\theta)\,X\,\widetilde{R}(\theta)\) as \(\theta\) runs through a range of angles. The number of dimensions goes up by one.
  • Surface of revolution. A surface swept by rotating a curve about an axis. Height and distance from the axis are preserved by the rotation.
  • Ruled surface. A surface made of straight lines. The cylinder, the cone and the hyperboloid of one sheet are all ruled.
  • Ring, horn and spindle torus. The three cases \(r<R\), \(r=R\) and \(r>R\) of one formula.
  • Pappus's centroid theorem. The volume of a solid of revolution is the area of the generating region times the distance its centroid travels, for a region that does not cross the axis.

References

  1. Dorst, L., Fontijne, D., & Mann, S. (2007). Geometric Algebra for Computer Science. Morgan Kaufmann.
  2. Hestenes, D. (1999). New Foundations for Classical Mechanics (2nd ed.). Kluwer Academic.
  3. De Keninck, S. ganja.js: Geometric algebra generator for JavaScript, C++, C#, Rust and Python. https://github.com/enkimute/ganja.js