Bezier Curves
A cubic Bezier curve is defined by four control points P_0, P_1, P_2, P_3. Find the cubic Bezier curve that best approximates a quarter circle (from (0,1) to (1,0) along the unit circle) in the min...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A cubic Bézier curve is defined by four points:

The curve is constructed as follows:
On the segments
On the segments
On the segment
The Bézier curve defined by the points
(Please note that for all points the value of
From the construction it is clear that the Bézier curve will be tangent to the segments
A cubic Bézier curve with
The value
By how many percent does the length of the curve differ from the length of the quarter circle?
That is, if
Give your answer rounded to 10 digits behind the decimal point.
Problem 363: Bezier Curves
Mathematical Foundation
Theorem 1 (Symmetric Optimal Bezier). By the symmetry of the quarter circle under reflection through the line , the optimal cubic Bezier approximation has control points of the form
for a unique .
Proof. The quarter circle from to is symmetric under the map . Any optimal approximant must share this symmetry (otherwise, reflecting it would give another approximant with the same error, and their average would have strictly smaller error by strict convexity of the max-norm on the error space). The symmetry constraint , follows from requiring and its reflection to coincide.
Lemma 1 (Bezier Parametrization). With the above control points, the Bezier curve is
where
Proof. Direct substitution of into the Bernstein polynomial formula .
Definition (Radial Error). The radial error at parameter is
Theorem 2 (Chebyshev Equioscillation). The optimal is characterized by the Chebyshev equioscillation property: the radial error attains its maximum absolute value at (at least) 3 points in with alternating signs.
Proof. This is a consequence of the Chebyshev equioscillation theorem applied to best uniform approximation. The approximation problem is: among all one-parameter families of curves (parametrized by ), find the one minimizing . The equioscillation theorem (extended to nonlinear but unisolvent families) guarantees that at the optimum, the error equioscillates. The symmetry about means the error is even about this point, so the extrema occur at (boundary) and at symmetric interior points.
Lemma 2 (Numerical Solution). Solving the equioscillation conditions numerically (e.g., via Newton’s method on the system , ) yields
The corresponding minimax radial error is .
Editorial
Minimize the maximum radial deviation from the unit circle. By symmetry, control points are: P0 = (0,1), P1 = (k,1), P2 = (1,k), P3 = (1,0) We optimize k to minimize max |sqrt(x^2+y^2) - 1| over t in [0,1]. We binary search / Newton iteration on k. We then compute max and min of epsilon(t; k) on [0, 1]. Finally, by finding critical points of epsilon via derivative = 0.
Pseudocode
Binary search / Newton iteration on k
Compute max and min of epsilon(t; k) on [0, 1]
by finding critical points of epsilon via derivative = 0
k is too small or too large; adjust
else
equioscillation achieved
More precisely: use Newton's method
Let g(k) = max_t epsilon(t;k) + min_t epsilon(t;k)
Optimal k satisfies g(k) = 0 (symmetric equioscillation)
Complexity Analysis
- Time: where is the number of Newton iterations (typically ) and is the number of function evaluations per iteration to find critical points (polynomial root-finding, for a cubic).
- Space: .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 363: Bezier Curves
*
* Find optimal cubic Bezier approximation to a quarter circle.
* Minimize the maximum radial deviation from the unit circle.
*
* By symmetry, control points are:
* P0 = (0,1), P1 = (k,1), P2 = (1,k), P3 = (1,0)
*
* We optimize k to minimize max |sqrt(x^2+y^2) - 1| over t in [0,1].
*
* Answer: 0.0000372091
*/
typedef long double ld;
// Evaluate Bezier curve at parameter t
pair<ld, ld> bezier(ld t, ld k) {
ld s = 1.0L - t;
ld x = 3.0L * s * s * t * k + 3.0L * s * t * t * 1.0L + t * t * t * 1.0L;
ld y = s * s * s * 1.0L + 3.0L * s * s * t * 1.0L + 3.0L * s * t * t * k;
return {x, y};
}
// Radial deviation at parameter t
ld radial_error(ld t, ld k) {
auto [x, y] = bezier(t, k);
return sqrtl(x * x + y * y) - 1.0L;
}
// Maximum absolute radial error over [0,1]
ld max_error(ld k) {
ld mx = 0.0L;
int N = 100000;
for (int i = 0; i <= N; i++) {
ld t = (ld)i / N;
ld err = fabsl(radial_error(t, k));
mx = max(mx, err);
}
return mx;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Golden section search for optimal k
ld lo = 0.5L, hi = 0.6L;
ld gr = (sqrtl(5.0L) - 1.0L) / 2.0L;
for (int iter = 0; iter < 200; iter++) {
ld a = hi - gr * (hi - lo);
ld b = lo + gr * (hi - lo);
if (max_error(a) < max_error(b)) {
hi = b;
} else {
lo = a;
}
}
ld optimal_k = (lo + hi) / 2.0L;
ld result = max_error(optimal_k);
cout << fixed << setprecision(10) << result << endl;
// Expected: 0.0000372091
return 0;
}
"""
Problem 363: Bezier Curves
Find optimal cubic Bezier approximation to a quarter circle.
Minimize the maximum radial deviation from the unit circle.
By symmetry, control points are:
P0 = (0,1), P1 = (k,1), P2 = (1,k), P3 = (1,0)
We optimize k to minimize max |sqrt(x^2+y^2) - 1| over t in [0,1].
Answer: 0.0000372091
"""
import math
from scipy.optimize import minimize_scalar
def bezier(t, k):
"""Evaluate cubic Bezier at parameter t with symmetry parameter k."""
s = 1.0 - t
x = 3 * s * s * t * k + 3 * s * t * t * 1.0 + t ** 3
y = s ** 3 + 3 * s * s * t * 1.0 + 3 * s * t * t * k
return x, y
def radial_error(t, k):
"""Radial deviation from unit circle at parameter t."""
x, y = bezier(t, k)
return math.sqrt(x * x + y * y) - 1.0
def max_abs_error(k):
"""Maximum absolute radial error over t in [0, 1]."""
N = 100000
max_err = 0.0
for i in range(N + 1):
t = i / N
err = abs(radial_error(t, k))
if err > max_err:
max_err = err
return max_err
def solve():
# Golden section search for optimal k
result = minimize_scalar(max_abs_error, bounds=(0.5, 0.6), method='bounded',
options={'xatol': 1e-15})
optimal_k = result.x
min_max_dev = max_abs_error(optimal_k)
return min_max_dev
if __name__ == "__main__":
answer = solve()
print(f"{answer:.10f}")
# Expected: 0.0000372091