The isoperimetric inequality

Of all closed curves of a given length, which one encloses the most area? The circle, and the isoperimetric inequality says by how much: for any curve of length \(L\) around an area \(A\),

\[4\pi A \le L^2,\]

with equality only for the circle. The isoperimetric quotient \(Q = 4\pi A / L^2\) is therefore 1 for a circle and less for every other shape, and it measures how round a shape is.

Here, planex2d measures the area and the length of several shapes exactly, and their quotients are checked against the closed forms.

Five shapes of the same perimeter, colored by their isoperimetric quotient

[1]:
import math

import planex as px
from scipy.special import ellipe

Shapes of one perimeter

The quotient does not depend on a shape’s size, so each shape is drawn at a convenient one. The shapes are a circle of radius 1, a Reuleaux triangle of width 1 from three arcs about the corners of a triangle, an ellipse of semi-axes 2 and 1, a square and an equilateral triangle. Their exact quotients are

  • \(2(\pi - \sqrt{3})/\pi\) for the Reuleaux triangle, of area \((\pi - \sqrt{3})/2\) and length \(\pi\);

  • \(4\pi^2 a b / L^2\) for the ellipse, of length \(L = 4a\,E(1 - b^2/a^2)\), with \(E\) the complete elliptic integral of the second kind;

  • \(\pi / (n \tan(\pi/n))\) for a regular polygon of \(n\) sides, \(\pi/4\) for the square.

[3]:
corners = [(0.0, 0.0), (1.0, 0.0), (0.5, math.sqrt(3) / 2)]
reuleaux = px.QuickSketch(corners[1]).Arc(center=corners[0], sweep=60).Arc(center=corners[1], sweep=60)
reuleaux.Arc(center=corners[2], sweep=60)
shapes = {
    "circle": (px.Circle((0, 0), 1).Face(), 1),
    "Reuleaux triangle": (reuleaux.Face(), 2 * (math.pi - math.sqrt(3)) / math.pi),
    "ellipse": (px.Face([px.Ellipse((0, 0), 2, 1)]), 4 * math.pi**2 * 2 / (4 * 2 * ellipe(1 - 1 / 4)) ** 2),
    "square": (px.QuickSketch().RectangleC(1, 1).Face(), math.pi / 4),
    "triangle": (px.QuickSketch().Polygon((0, 0), 1, 3).Face(), math.pi / (3 * math.tan(math.pi / 3))),
}
for name, (face, exact) in shapes.items():
    print(name, "| Q", 4 * math.pi * face.mass / face.outer.mass**2, "| exact", exact)
circle | Q 1.0 | exact 1
Reuleaux triangle | Q 0.8973422091564158 | exact 0.8973422091564159
ellipse | Q 0.8411651810063179 | exact 0.8411651810063192
square | Q 0.7853981633974483 | exact 0.7853981633974483
triangle | Q 0.6045997880780726 | exact 0.6045997880780728
Circle, Q = 1.000
(a) Circle, Q = 1.000
Reuleaux triangle, Q = 0.897
(b) Reuleaux triangle, Q = 0.897
Ellipse, Q = 0.841
(c) Ellipse, Q = 0.841
Square, Q = 0.785
(d) Square, Q = 0.785
Triangle, Q = 0.605
(e) Triangle, Q = 0.605
Figure 1: Five shapes and their isoperimetric quotients

Polygons toward the circle

The more sides a regular polygon has, the closer it comes to the circle, and its quotient rises toward 1 (Figure 2):

isoperimetric quotient over number of sides: regular polygons 3 0.605, 4 0.785, 5 0.865, 6 0.907, 7 0.932, 8 0.948, 9 0.959, 10 0.967, 11 0.973, 12 0.977, 13 0.98, 14 0.983, 15 0.985, 16 0.987, 17 0.989, 18 0.99, 19 0.991, 20 0.992, 21 0.993, 22 0.993, 23 0.994, 24 0.994
Figure 2: Regular polygons against the circle

Dido’s problem

Dido’s problem, named after the legend of Queen Dido’s ox hide, asks for the most land along a straight coast. The coast closes the curve for free, and a rope of length \(\ell\) then encloses the most area as a half circle, the mirror image of the isoperimetric circle, with the area \(\ell^2 / (2\pi)\). A rectangle with the same rope, best as twice as long as it is deep, encloses only \(\ell^2/8\):

[6]:
rope = 100.0
r = rope / math.pi
half = px.QuickSketch((-r, 0)).Line(2 * r).Turn(90).Arc(r, 180).Face()
box = px.QuickSketch((-rope / 4, 0)).Rectangle(rope / 2, rope / 4).Face()
print("half circle", half.mass, "| ℓ²/2π", rope**2 / (2 * math.pi), "| rope", half.outer.mass - 2 * r)
print("rectangle", box.mass, "| ℓ²/8", rope**2 / 8, "| rope", box.outer.mass - rope / 2)
half circle 1591.5494309189532 | ℓ²/2π 1591.5494309189535 | rope 100.0
rectangle 1250.0 | ℓ²/8 1250.0 | rope 100.0