The Brachistochrone problem asks the question "what is the shape of the curve down which a bead sliding from rest and accelerated by gravity will slip, without friction, from one fixed point, \(P_1\) to another \(P_2\) in the least time?"
Its solution is well-known and given in various forms in many places on the internet, but is given in outline at the bottom of this post.
Paths between \(P_1 = (0,0)\) and \(P_2 = (1, 0.65)\):

Note that the path giving the shortest time (the cycloid) is not the shortest distance between the points and may have a minimum (i.e. the bead slides down and then up before reaching \(P_2\), as shown by the following example for \(P_2 = (1, 0.3)\).

The following Python program plots the Brachistochrone curve (an arc of a cycloid) and calculates the time of travel. It is also compared with three other paths: (i) a straight line, (ii) a circular path with a vertical tangent at \(P_1\) and (iii) a parabola with vertical tangent at \(P_1\).
import numpy as np
from scipy.optimize import newton
from scipy.integrate import quad
import matplotlib.pyplot as plt
# Acceleration due to gravity (m.s-2); final position of bead (m).
g = 9.81
x2, y2 = 1, 0.65
def cycloid(x2, y2, N=100):
"""Return the path of Brachistochrone curve from (0,0) to (x2, y2).
The Brachistochrone curve is the path down which a bead will fall without
friction between two points in the least time (an arc of a cycloid).
It is returned as an array of N values of (x,y) between (0,0) and (x2,y2).
"""
# First find theta2 from (x2, y2) numerically (by Newton-Rapheson).
def f(theta):
return y2/x2 - (1-np.cos(theta))/(theta-np.sin(theta))
theta2 = newton(f, np.pi/2)
# The radius of the circle generating the cycloid.
R = y2 / (1 - np.cos(theta2))
theta = np.linspace(0, theta2, N)
x = R * (theta - np.sin(theta))
y = R * (1 - np.cos(theta))
# The time of travel
T = theta2 * np.sqrt(R / g)
print('T(cycloid) = {:.3f}'.format(T))
return x, y, T
def linear(x2, y2, N=100):
"""Return the path of a straight line from (0,0) to (x2, y2)."""
m = y2 / x2
x = np.linspace(0, x2, N)
y = m*x
# The time of travel
T = np.sqrt(2*(1+m**2)/g/m * x2)
print('T(linear) = {:.3f}'.format(T))
return x, y, T
def func(x, f, fp):
"""The integrand of the time integral to be minimized for a path f(x)."""
return np.sqrt((1+fp(x)**2) / (2 * g * f(x)))
def circle(x2, y2, N=100):
"""Return the path of a circular arc between (0,0) to (x2, y2).
The circle used is the one with a vertical tangent at (0,0).
"""
# Circle radius
r = (x2**2 + y2**2)/2/x2
def f(x):
return np.sqrt(2*r*x - x**2)
def fp(x):
return (r-x)/f(x)
x = np.linspace(0, x2, N)
y = f(x)
# Calcualte the time of travel by numerical integration.
T = quad(func, 0, x2, args=(f, fp))[0]
print('T(circle) = {:.3f}'.format(T))
return x, y, T
def parabola(x2, y2, N=100):
"""Return the path of a parabolic arc between (0,0) to (x2, y2).
The parabola used is the one with a vertical tangent at (0,0).
"""
c = (y2/x2)**2
def f(x):
return np.sqrt(c*x)
def fp(x):
return c/2/f(x)
x = np.linspace(0, x2, N)
y = f(x)
# Calcualte the time of travel by numerical integration.
T = quad(func, 0, x2, args=(f, fp))[0]
print('T(parabola) = {:.3f}'.format(T))
return x, y, T
# Plot a figure comparing the four paths.
fig, ax = plt.subplots()
for curve in ('cycloid', 'circle', 'parabola', 'linear'):
x, y, T = globals()[curve](x2, y2)
ax.plot(x, y, lw=4, alpha=0.5, label='{}: {:.3f} s'.format(curve, T))
ax.legend()
ax.set_xlabel('$x$')
ax.set_xlabel('$y$')
ax.set_xlim(0, 1)
ax.set_ylim(0.8, 0)
plt.savefig('brachistochrone.png')
plt.show()
Appendix A: Solution the the Brachistochrone problem
We choose \(P_1 = (0,0)\) and set \(P_2 = (x_2, y_2)\), with the \(y-\)axis pointing in the same direction as the acceleration due to gravity, \(\boldsymbol{g}\). Then we seek to minimize
where the arc length element along the curve we seek is \(\mathrm{d}s = \sqrt{\mathrm{d}x^2 + \mathrm{d}y^2}\) and the speed along the curve, \(v\) satisfies \(\frac{1}{2}mv^2 = mgy\) by conservation of energy. Then the functional to be minimized is
where \(y' = \mathrm{d}y/\mathrm{d}x\). The function to be varied in this minimization,
does not explicitly depend on \(x\) so the Beltrami identity applies:
Now,
and substitution into the Beltrami identity gives
This differential equation has a parametric solution in the form of a cycloid:
The parameter \(\theta\) varies from \(0\) at \(P_1 = (0,0)\) to \(\theta_2\) at \(P_2 = (x_2, y_2)\) which may be found numerically as the solution to
Substitution back into the second parametric equation then gives
Appendix B: Paths and times for other curves
Straight line
The straight line between \(P_1 = (0,0)\) and \(P_2 = (x_2,y_2)\) has the equation \(y = mx\) with \(m=y_2/x_2\). The time taken is
Circular arc
The circle through \(P_1 = (0,0)\) and \(P_2 = (x_2,y_2)\) with vertical tangent at \(P_1\) has the formula \(y^2 = r^2 - (x-r)^2\) with radius
The integral giving \(T\) may be evaluated numerically using \(y = \sqrt{2xr-x^2}\) and \(y' = (r-x)/y\).
Parabolic arc
The parabola through \(P_1 = (0,0)\) and \(P_2 = (x_2,y_2)\) with vertical tangent at \(P_1\) has the formula \(y = \sqrt{cx}\) with \(c = (y_2/x_2)^2\). The integral giving \(T\) may be evaluated numerically using this and \(y' = c/(2y)\).