Books · The Fiddler: Solutions
Chapter 100
Can You Eclipse via Ellipse?
Two congruent ellipses together cover a unit circle (radius ). The ellipses may have any eccentricity, as long as they are congruent to each other. What is the smallest possible area of one such ellipse?
The Fiddler, Zach Wissner-Gross, April 12, 2024(original post)
Solution
Split the disc along a diameter. By symmetry the two congruent ellipses should share the work evenly, one to each half-disc, and a half-disc is convex, so an ellipse covers it the moment it contains the bounding diameter and the semicircular arc. Centre a candidate on the axis of symmetry, and minimise its area subject to covering the upper half-disc. The minimum sits at a wide, shallow ellipse that hugs the flat diameter while just cresting the arc. Its area is :
The computation
Encode the covering condition directly: sample the half-disc densely (arc, diameter, centre) and minimise over the ellipse parameters under the constraint that every sampled point lies inside. The optimum matches .
import numpy as np, math
from scipy.optimize import minimize
th = np.linspace(0, math.pi, 400)
pts = np.vstack([np.c_[np.cos(th), np.sin(th)], [[1, 0], [-1, 0], [0, 0]]])
def contains(p): # half-disc inside ellipse?
a, b, k = p
return 1 - ((pts[:, 0] / a) ** 2 + ((pts[:, 1] - k) / b) ** 2).max()
r = minimize(lambda p: math.pi * p[0] * p[1], [1.2, 0.7, 0.3],
constraints=[{'type': 'ineq', 'fun': contains}],
bounds=[(.5, 3), (.3, 3), (-1, 1)], method='SLSQP')
print(r.fun, 4 * math.pi * math.sqrt(3) / 9) # 2.4184 2.4184
Extra Credit
What is the smallest area when three congruent ellipses cover the unit circle?
Solution
Now divide the disc into three sectors, one per ellipse, each sector again convex. Place the ellipse symmetrically on its sector’s bisector. The smallest one passes through the sector’s three corners, the apex at the centre and the two ends of the arc at : its centre lands at with semi-axes A short check confirms this ellipse also clears the curved edge and the two straight edges, so it covers the whole sector, with area : Three of them, rotated by , cover the disc, and as expected sharing the work among more ellipses lets each be smaller.
The computation
The same optimisation over a sector, with its bisector along the axis, recovers the semi-axes and the area.
import numpy as np, math
from scipy.optimize import minimize
th = np.linspace(-math.pi / 3, math.pi / 3, 200)
arc = np.c_[np.cos(th), np.sin(th)]
t = np.linspace(0, 1, 80)[:, None]
edges = np.vstack([t * [math.cos(math.pi/3), math.sin(math.pi/3)],
t * [math.cos(math.pi/3), -math.sin(math.pi/3)]])
rr, aa = np.meshgrid(np.linspace(0, 1, 40), np.linspace(-math.pi/3, math.pi/3, 40))
interior = np.c_[(rr * np.cos(aa)).ravel(), (rr * np.sin(aa)).ravel()]
pts = np.vstack([arc, edges, interior])
def contains(p): # sector inside ellipse on the x-axis?
a, b, k = p
return 1 - (((pts[:, 0] - k) / a) ** 2 + (pts[:, 1] / b) ** 2).max()
r = minimize(lambda p: math.pi * p[0] * p[1], [0.5, 0.9, 0.5],
constraints=[{'type': 'ineq', 'fun': contains}],
bounds=[(.1, 2), (.1, 2), (-1, 1)], method='SLSQP')
print(round(r.fun, 4), round(math.sqrt(3) * math.pi / 4, 4)) # 1.360 1.360