What is a Bezier Curve?

Rohan Joseph
Data Science Shorts
5 min readMar 1, 2024
Source : Giphy

A Bezier curve is a type of continuous or polynomial curve that is widely used in computer graphics, animation, and design. In data science, they can be used for visualizing smooth trends in the data, interpolate missing data in time series and model relationships between variables in the data.

It is a curve which is defined by a set of points, where the first and last points are the end points of the curve, whereas the intermediate points do not typically lie on the curve — however they determine the shape of the curve.

Linear Bezier Curve:

Plot two points P₀(6,2) and P₁(8,4)

The Bezier Curve is just a line between these two points, represented by the formula (also called linear interpolation):

B(t) = P₀*(1-t) + P₁*(t), where 0 ≤t ≤1

Code available below to generate the above graph. Plotting a line can be much simpler — but doing it the Bezier Curve way to understand the concept.

# Import packages
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
%matplotlib notebook
%matplotlib inline


# x axis values
x = [6,8]
# y axis values
y = [2,4]

# Establish the t values
t_values = np.arange(0,1.05,0.05)

# Bezier Curve for various values of t
x_poly = list()
y_poly = list()
for t in t_values:
#print(t)
x_poly.append((t*x[0] + (1-t)*x[1]))
y_poly.append(t*y[0] + (1-t)*y[1])

fig, ax = plt.subplots()
# plotting the points
plt.scatter(x, y,label = 'Linear')
plt.plot(x_poly, y_poly, label = 'Bezier Curve', color = 'green')

# naming the x axis
plt.xlabel('x - axis')
# naming the y axis
plt.ylabel('y - axis')

ax.text(6,2.1,"$P_0$")
ax.text(8,3.8,"$P_1$")


# function to show the plot
plt.show()

Quadratic Bezier Curve:

Plot three points P₀(6,2), P₁(8,4) and P₂ (10,2)

For a Quadratic Bezier Curve, first we need to draw two Linear Beziers joining P₀ to P₁ (Q₀), and P₁ to P₂ (Q₁)

Now, do a linear interpolation between Q₀ and Q₁ (Note that Q₀ and Q₁ represent the linear Bezier curves) :

B(t) = Q₀*(t) + Q₁*(1-t), where 0 ≤t ≤1

where,

Q₀ = P₀*(1-t) + P₁*(t)

Q₁ = P₁*(1-t) + P₂*(t)

The path traced by the function B(t) is the Bezier curve, which is represented in green below.

Code to find the Linear/Quadratic Bezier curves :

# x axis values
x = [6,8,10]
# y axis values
y = [2,4,2]


# Find the linear Bezier Curves
Q0_x = list()
Q0_y = list()
Q1_x= list()
Q1_y= list()
for t in t_values:
#print(t)

Q0_x.append((1-t)*x[0] + (t)*x[1])
Q0_y.append((1-t)*y[0] + (t)*y[1])

Q1_x.append((1-t)*x[1] + (t)*x[2])
Q1_y.append((1-t)*y[1] + (t)*y[2])

# Find the Quadratic Bezier Curve
R0_x = list()
R0_y = list()
for i in range(len(t_values)):
R0_x.append(((1-t_values[i])*Q0_x[i] + (t_values[i])*Q1_x[i]))
R0_y.append(((1-t_values[i])*Q0_y[i] + (t_values[i])*Q1_y[i]))

Code to plot the Quadratic Bezier curve animation (above) :



def quadratic_bezier(current):
# if animation is at the last frame, stop it


#fig, ax = plt.subplots()
plt.cla()

fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.rcParams.update({'font.size': 22})
if current == len(Q0_x)-1:
a.event_source.stop()


# plotting the points
plt.plot(x, y,label = 'Linear', linewidth=5)

if current < len(Q0_x)-2:
plt.plot([Q0_x[current],Q1_x[current]], [Q0_y[current],Q1_y[current]], linewidth=5)
else :
plt.plot([Q0_x[len(Q0_x)-1],Q1_x[len(Q0_x)-1]], [Q0_y[len(Q0_x)-1],Q1_y[len(Q0_x)-1]], linewidth=5)


plt.plot(R0_x[0:current], R0_y[0:current], label = 'Bezier Curve', linewidth=5)

# naming the x axis
plt.xlabel('x - axis')
# naming the y axis
plt.ylabel('y - axis')

plt.text(6,2.1,"$P_0$")
plt.text(8,3.8,"$P_1$")
plt.text(10,2.1,"$P_2$")

plt.text(7.75,2.75,"Bezier Curve")



fig = plt.figure()
a = animation.FuncAnimation(fig, quadratic_bezier, interval=200)
a.save('quadratic_bezier.gif', writer="pillow")

Cubic Bezier Curve:

Plot four points P₀(6,2), P₁(8,4) and P₂ (10,2) and P₃ (15,3)

For a Cubic Bezier Curve, first we need to draw three Linear Beziers joining P₀ to P₁ (Q₀), and P₁ to P₂ (Q₁) and P₂ to P₃ (Q₂)

Now, draw two intermediate Bezier Curves Q₀ to Q₁ (B₀), and Q₁ and Q₂ (B₁). Finally, the Cubic Bezier Curve is the Bezier Curve between B₀ and B₁.

B(t) = B₀*(t) + B₁*(1-t), where 0 ≤t ≤1

where,

B₀ = Q₀*(1-t) + Q₁*(t)

B₁ = Q₁*(1-t) + Q₂*(t)

Q₀ = P₀*(1-t) + P₁*(t)

Q₁ = P₁*(1-t) + P₂*(t)

The path traced by the function B(t) is the Bezier curve, which is represented in green below.

Code to find the Cubic Bezier curves :

fig, ax = plt.subplots()
# x axis values
x = [6,8,10,15]
# corresponding y axis values
y = [2,4,2,3]


fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.rcParams.update({'font.size': 18})


plt.scatter(x, y,label = 'Linear')

plt.text(6,2.1,"$P_0$")
plt.text(8,3.8,"$P_1$")
plt.text(10,2.1,"$P_2$")
plt.text(15,2.8,"$P_3$")

# plotting the points
plt.plot(x, y,label = 'Linear',color = 'green', linewidth=3)

#plt.plot(R0_x, R0_y, label = 'Bezier Curve')

# naming the x axis
plt.xlabel('x - axis')
# naming the y axis
plt.ylabel('y - axis')

# function to show the plot
plt.show()

Q0_x = list()
Q0_y = list()
Q1_x = list()
Q1_y = list()

for t in t_values:
#print(t)
Q0_x.append((1-t)*((1-t)*x[0] + (t)*x[1]) + (t)*((1-t)*x[1] + (t)*x[2]))
Q0_y.append((1-t)*((1-t)*y[0] + (t)*y[1]) + (t)*((1-t)*y[1] + (t)*y[2]))

Q1_x.append((1-t)*((1-t)*x[1] + (t)*x[2]) + (t)*((1-t)*x[2] + (t)*x[3]))
Q1_y.append((1-t)*((1-t)*y[1] + (t)*y[2]) + (t)*((1-t)*y[2] + (t)*y[3]))

R0_x = list()
R0_y = list()
for i in range(len(t_values)):
R0_x.append(((1-t_values[i])*Q0_x[i] + (t_values[i])*Q1_x[i]))
R0_y.append(((1-t_values[i])*Q0_y[i] + (t_values[i])*Q1_y[i]))

Code to plot the Cubic Bezier curve animation (above) :


def cubic_bezier(current):
# if animation is at the last frame, stop it


#fig, ax = plt.subplots()
plt.cla()

fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.rcParams.update({'font.size': 22})
if current == len(Q0_x)-1:
a.event_source.stop()




if current < len(Q0_x)-2:
plt.plot([Q0_x[current],Q1_x[current]], [Q0_y[current],Q1_y[current]], linewidth=5)
else :
plt.plot([Q0_x[len(Q0_x)-1],Q1_x[len(Q0_x)-1]], [Q0_y[len(Q0_x)-1],Q1_y[len(Q0_x)-1]], linewidth=5)


plt.plot(R0_x[0:current], R0_y[0:current], label = 'Bezier Curve', linewidth=5)

# plotting the points
plt.plot(x, y,label = 'Linear', color = 'green', linewidth=3)
plt.scatter(x, y,label = 'Linear')

# naming the x axis
plt.xlabel('x - axis')
# naming the y axis
plt.ylabel('y - axis')

plt.text(6,2.1,"$P_0$")
plt.text(8,3.8,"$P_1$")
plt.text(10,2.1,"$P_2$")

plt.text(7.75,2.75,"Bezier Curve")



fig = plt.figure()
a = animation.FuncAnimation(fig, quadratic_bezier, interval=200)
a.save('cubic_bezier.gif', writer="pillow")

References :

  1. https://www.youtube.com/watch?v=jvPPXbo87ds
  2. https://en.wikipedia.org/wiki/B%C3%A9zier_curve#:~:text=A%20B%C3%A9zier%20curve%20(%2F%CB%88b,by%20means%20of%20a%20formula.

Connect on LinkedIn and, check out Github (below) for the complete notebook.

--

--