Bezier Curves
Bounding Box
Algorithm Development
Computer Graphics
Computational Geometry

An algorithm to find bounding box of closed bezier curves?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A closed Bezier path does not need a special "closed-curve formula" for its bounding box. The usual approach is to compute the bounds of each Bezier segment, then take the union of those segment bounds. The important step is finding interior extrema, not just looking at control points.

Why Control Points Alone Are Not Enough

A Bezier curve always lies inside the convex hull of its control points, but the control-point box is only a safe outer box. It is not always the tight bounding box of the curve itself.

To get the exact axis-aligned bounds, you must evaluate the curve at:

  • segment endpoints
  • interior parameter values where dx/dt = 0
  • interior parameter values where dy/dt = 0

For a closed path made of multiple segments, repeat that process for every segment and merge the results.

Cubic Segment Mathematics

A cubic Bezier segment with control points P0, P1, P2, and P3 can be written separately for x and y coordinates. The extrema occur where the derivative is zero.

For a cubic, the derivative is quadratic, so you solve a quadratic equation for x and another for y, keeping only roots in [0, 1].

That is the central algorithmic idea.

A Practical Python Implementation

The following code computes the bounding box of a cubic Bezier segment.

python
1import math
2
3
4def cubic_value(p0, p1, p2, p3, t):
5    mt = 1.0 - t
6    return (
7        mt**3 * p0 +
8        3 * mt**2 * t * p1 +
9        3 * mt * t**2 * p2 +
10        t**3 * p3
11    )
12
13
14def quadratic_roots(a, b, c):
15    if abs(a) < 1e-12:
16        if abs(b) < 1e-12:
17            return []
18        return [-c / b]
19
20    disc = b * b - 4 * a * c
21    if disc < 0:
22        return []
23    if disc == 0:
24        return [-b / (2 * a)]
25
26    s = math.sqrt(disc)
27    return [(-b + s) / (2 * a), (-b - s) / (2 * a)]
28
29
30def cubic_extrema_1d(p0, p1, p2, p3):
31    a = -p0 + 3 * p1 - 3 * p2 + p3
32    b = 2 * (p0 - 2 * p1 + p2)
33    c = -p0 + p1
34    return [t for t in quadratic_roots(3 * a, 3 * b, 3 * c) if 0.0 <= t <= 1.0]
35
36
37def cubic_bbox(points):
38    (x0, y0), (x1, y1), (x2, y2), (x3, y3) = points
39    ts = {0.0, 1.0}
40    ts.update(cubic_extrema_1d(x0, x1, x2, x3))
41    ts.update(cubic_extrema_1d(y0, y1, y2, y3))
42
43    xs = [cubic_value(x0, x1, x2, x3, t) for t in ts]
44    ys = [cubic_value(y0, y1, y2, y3, t) for t in ts]
45    return min(xs), min(ys), max(xs), max(ys)
46
47
48curve = ((0, 0), (2, 5), (4, -2), (6, 1))
49print(cubic_bbox(curve))

This gives the exact axis-aligned box for one cubic segment.

Extending to a Closed Path

A closed shape is usually a sequence of Bezier segments whose last endpoint returns to the first. Compute each segment's bounding box, then merge them.

python
1
2def union_boxes(boxes):
3    min_x = min(box[0] for box in boxes)
4    min_y = min(box[1] for box in boxes)
5    max_x = max(box[2] for box in boxes)
6    max_y = max(box[3] for box in boxes)
7    return min_x, min_y, max_x, max_y

So the full algorithm is:

  1. split the closed path into Bezier segments
  2. compute each segment's exact box from endpoints plus derivative roots
  3. union all segment boxes

Closure changes only how the segments connect. It does not change the bounding-box math for an individual segment.

Quadratic Beziers Are Even Simpler

For quadratic Beziers, dx/dt and dy/dt are linear instead of quadratic. That means each axis has at most one interior candidate t value.

The same logic still applies: endpoints plus derivative roots in [0, 1].

Numerical Considerations

Use a small epsilon when deciding whether coefficients are effectively zero. Near-degenerate curves can behave like lower-degree curves numerically, and direct quadratic formulas can become unstable if you ignore that.

Also remember that you are finding an axis-aligned bounding box. If you need the minimum-area rotated box, that is a different problem.

Common Pitfalls

A common mistake is using only the endpoints. Internal extrema can easily fall between them.

Another mistake is assuming a closed path needs one global Bezier equation. In most graphics formats, a closed path is just a chain of segments whose last point reconnects to the first.

Developers also sometimes use the control-point box and call it exact. It is safe, but it can be looser than the true curve bounds.

Summary

  • Compute bounds per Bezier segment, not with one special closed-curve formula.
  • Exact axis-aligned bounds require endpoints plus derivative-root extrema.
  • For cubic segments, solve quadratic equations for dx/dt = 0 and dy/dt = 0.
  • For a closed path, union the boxes of all segments.
  • Control-point bounds are safe but not always tight.

Course illustration
Course illustration

All Rights Reserved.