Skip to content
Vamshi Jandhyala

Books · The Fiddler: Solutions

Chapter 14

Can You Trace the Locus?

I have a loop of string whose total length is 1010. I place it around a unit disk (radius 11) and pull a point on the string away from the disk until the string is taut. I then drag this point around the disk in all directions, always keeping the string taut, so the point traces out a loop. What is the area inside this loop?

The Fiddler, Zach Wissner-Gross, March 20, 2026(original post)

The taut string around the unit disk, pulled to a point. Figure from the source post.

Solution

Pulled taut to a point PP, the string hugs the far side of the disk and runs straight along the two tangent lines to PP. That shape is exactly the boundary of the convex hull of the disk together with PP, so the string’s length is the perimeter of that hull: the far arc plus the two tangent segments. If PP lies at distance dd from the centre, each tangent has length x=d21x=\sqrt{d^2-1}, and the near arc of measure 2arctanx2\arctan x is replaced by the tangents, leaving L=(2π2arctanx)+2x.L = \bigl(2\pi - 2\arctan x\bigr) + 2x. This depends only on dd, so for a fixed string length the distance dd is the same in every direction: the traced loop is a circle centred at the disk’s centre. Setting L=10L = 10, 2x2arctanx=102π,x=3.1189,2x - 2\arctan x = 10 - 2\pi,\qquad x = 3.1189\ldots, and the enclosed area is πd2=π(1+x2)=33.70.\pi d^2 = \pi\bigl(1 + x^2\bigr) = \boxed{33.70\ldots}.

The computation

Solve the taut-string condition: find the tangent length xx at which the convex-hull perimeter 2π2arctanx+2x2\pi-2\arctan x+2x equals the string length 1010, then the traced circle has radius 1+x2\sqrt{1+x^2} and area π(1+x2)\pi(1+x^2).

from math import atan, pi
from scipy.optimize import brentq
x = brentq(lambda x: 2*x - 2*atan(x) - (10 - 2*pi), 0.1, 100)
print(round(pi * (1 + x*x), 4))      # 33.7023

Extra Credit

Now the loop of string has length 1414, and I place it around two adjacent unit disks before pulling a point taut and dragging it around. What is the area inside the traced loop?

The same construction around two touching unit disks. Figure from the source post.

Solution

The two touching disks have, as their convex hull, a stadium: two unit semicircles joined by straight sides of length 22. The taut string still traces the boundary of the convex hull of the obstacle and the point PP, so the loop is the set of points PP for which that hull has perimeter 1414. The stadium is not a circle, so the loop is not one either, and the area has no tidy closed form. Tracing it numerically gives 52.36.\boxed{52.36\ldots}.

The computation

Build the two-disk obstacle as points. In each direction, root-find the distance at which the convex hull of the obstacle plus the pulled point has perimeter 1414; that locus of points is the traced loop, and the shoelace formula gives its area.

import numpy as np
from scipy.spatial import ConvexHull
from scipy.optimize import brentq
def disk(cx, n=2000):
    t = np.linspace(0, 2*np.pi, n, endpoint=False)
    return np.c_[cx + np.cos(t), np.sin(t)]
K = np.vstack([disk(-1), disk(1)])          # unit disks, centres (-1,0),(1,0)
def perim(P):
    w = np.vstack([K, P]); v = w[ConvexHull(w).vertices]
    return np.linalg.norm(np.diff(np.vstack([v, v[0]]), axis=0), axis=1).sum()
pts = []
for a in np.linspace(0, 2*np.pi, 720, endpoint=False):
    r = brentq(lambda r: perim([r*np.cos(a), r*np.sin(a)]) - 14, 2, 60)
    pts.append([r*np.cos(a), r*np.sin(a)])
p = np.array(pts)
print(round(0.5*abs((p[:, 0]*np.roll(p[:, 1], -1)
                     - np.roll(p[:, 0], -1)*p[:, 1]).sum()), 2))   # 52.36