Enclosing Circle
The smallest circle containing all points. Unique, and determined by at most 3 of the points.
The key facts
- The minimum enclosing circle is unique.
- It is determined by 2 points (as a diameter) or 3 points (on its boundary).
- Therefore a brute-force solution exists — but Welzl’s algorithm does it in expected .
Proof: uniqueness and the -point bound
Uniqueness. Suppose two distinct minimum circles of the same minimal radius both enclose the point set. Their intersection is a lens; consider the circle with diameter equal to the shorter of the two arcs connecting ‘s two crossing points, specifically: the circle through those two crossing points with the smallest radius that still contains the lens region — concretely, the midpoint circle construction shows that the circle with centre at the midpoint of ‘s centres and a carefully chosen smaller radius still covers all input points (since every point in a convex lens is covered by a slightly smaller circle centred between the two centres — a standard convexity argument: the intersection of two disks of radius is contained in a disk of radius centred at the midpoint of the two centres whenever the centres are distinct), contradicting minimality of . So .
points. If the minimum circle has no point on its boundary at all, it can be shrunk — contradiction, so at least one point is on the boundary. If exactly one, it can be shrunk toward that point — contradiction (shrinking slightly towards the single boundary point keeps it inside while reducing the radius, since no other point constrains it), so at least two points are on the boundary whenever the circle cannot be perturbed, UNLESS a single point already forces the radius to (). With exactly two boundary points: if they are not diametrically opposite, the circle can be shrunk and re-centred slightly toward the midpoint of the two points while still covering both and, since no third point is on the boundary to block this, still covering everything else — contradiction — so with exactly two boundary points they must be a diameter. With three or more boundary points, if all three (any three, in fact) do not already pin the circle uniquely (i.e. if a smaller circle through a subset still covers everything), the argument reduces to the two-point or one-point case; otherwise three points already determine the unique circumscribing circle, and a fourth point on the boundary would be a redundant constraint (it must lie on the same circle, since the circle is already fully pinned by three).
Welzl’s algorithm — expected
struct Circle { PD c; double r; };
bool inside(const Circle& ci, PD p) { return norm2(p - ci.c) <= ci.r * ci.r + EPS; }
Circle from2(PD a, PD b) { return {(a + b) * 0.5, abs_(a - b) / 2}; }
Circle from3(PD a, PD b, PD c) { PD o = circumcenter(a, b, c); return {o, abs_(o - a)}; }
Circle minEnclosingCircle(vector<PD> p) {
shuffle(p.begin(), p.end(), rng); // ESSENTIAL
Circle c{p[0], 0};
for (int i = 0; i < (int)p.size(); i++) {
if (inside(c, p[i])) continue;
c = {p[i], 0};
for (int j = 0; j < i; j++) {
if (inside(c, p[j])) continue;
c = from2(p[i], p[j]);
for (int k = 0; k < j; k++) {
if (inside(c, p[k])) continue;
c = from3(p[i], p[j], p[k]);
}
}
}
return c;
}Three nested loops that look — but the analysis says otherwise. (circumcenter: Triangles; degenerate when the three points are collinear, in which case the enclosing circle is determined by the two extreme points, which the algorithm’s structure already handles since that case is caught by the from2 level before three points are ever fixed together.)
Proof: Welzl's algorithm is correct
Invariant. After processing index ,
cis the minimum enclosing circle of . By induction: if is already inside the circle for , that circle is still minimal and enclosing for too (adding an already-covered point changes nothing). If is outside, it must lie on the boundary of the new minimum circle: if it didn’t, the same circle (minus ‘s constraint) would still be the minimum enclosing circle for , but then it would also enclose while being a different, and since it must have radius the true minimum for the smaller set, this doesn’t immediately contradict anything — the real argument is simpler: the minimum enclosing circle of has radius that of (more points, no smaller circle can work), and if were strictly interior to it, removing from the constraint set wouldn’t shrink the circle (it’s still forced by the others) — but outside the old circle while interior to the new one is consistent, so the correct statement is: is outside the circle of the first points, and the new minimum circle (for points) must be at least that circle’s size; if were in the new circle’s interior, shrinking the new circle slightly toward where it’s “tight” would still have to keep outside (since was outside the smaller, -point circle, which the new one must enclose) — forcing onto the boundary is exactly the condition that the new minimum circle enclosing all points and touching the constraint imposed by cannot do better than placing exactly on its edge.
The same argument nests: having fixed on the boundary, among reduce to the sub-problem “smallest circle through enclosing the rest”, and if some () violates the current circle-through-, it must also sit on the boundary of the correct circle — by the identical argument one level down. With two points fixed, a circle through both is a one-parameter family (centres along the perpendicular bisector); a third violating point pins it uniquely viafrom3, and since a circle is determined by at most 3 boundary points (proved above), the recursion never needs a fourth level.Expected (backward analysis). The final circle is determined by at most 3 of the points. For a uniformly random insertion order, by symmetry the probability that the -th point (in the random order) is one of those “defining” points is at most — so the expected work triggered at step (an re-scan when the point is outside the current circle) is . The identical argument applies one nesting level down (fixing one point, the sub-problem over the remaining in their random relative order has the same structure with combinatorial dimension 2) and two levels down (dimension 1), each contributing expected work per step. Summing over at each of the (constant) nesting depths gives total expected time.
The shuffle is not optional
Without it, an adversarial input (points already sorted so each new one is outside) makes the algorithm . Shuffle with a well-seeded RNG so the order cannot be predicted by whoever constructed the test data.
Tested: minEnclosingCircle checked to enclose every input point (within ) and matched in radius against a brute-force search (every pair as a diameter, every triple as a circumscribed circle, keeping the smallest that encloses all points) on random point sets up to ; also checked on adversarial sorted/collinear inputs to confirm the shuffled version still returns the correct circle (only the unshuffled version would blow up in time, not in correctness, on such inputs).
LP-type problems
Minimum enclosing circle is the archetypal LP-type problem: an optimisation over a set system with bounded combinatorial dimension (3 here), satisfying monotonicity and locality. The same framework solves:
| Problem | Combinatorial dimension |
|---|---|
| Minimum enclosing circle | 3 |
| Minimum enclosing ball in | |
| Minimum enclosing ellipse | 5 |
| Smallest enclosing annulus | 4 |
| Linear programming in dimension | |
| Distance between two polytopes | |
| Largest ball inside a polytope |
Recognising a problem as LP-type tells you immediately that a randomised incremental algorithm is — see Seidel’s LP for the same framework applied to linear programming, and randomised incremental Delaunay for another application of the same backward-analysis technique.
Variants
| Variant | Method |
|---|---|
| Minimum enclosing rectangle | rotating calipers on the hull (Toussaint) — 07-rotating-calipers |
| Minimum enclosing square | binary search on the side + a sweep |
| Smallest circle covering of points | much harder; or worse |
| Circle covering all with a fixed radius | is the intersection of the disks non-empty? |
| Largest empty circle | a Voronoi vertex, hull edge, or bounding-box constraint — 20-delaunay-and-voronoi |
| Minimum enclosing ball in 3D | Welzl with dimension 4 |
| Circle minimising the sum of distances | the geometric median — no closed form; use Weiszfeld’s iteration or nested ternary search |
The last row is worth flagging: minimising the maximum distance gives the enclosing circle (LP-type, ), while minimising the sum gives the geometric median, a different and harder problem with no exact algorithm.
Preprocessing with the hull
Only points on the convex hull can determine the circle (an interior point is never one of the boundary-defining points, since it’s never extreme in any direction), so taking the hull first reduces to . Usually not worth it — Welzl is already linear — but useful when the hull is needed anyway.