Beziers, curves and paths

Bezier curves are a mathematical approximation of natural geometric shapes. We use them to represent a curve with as little information as possible and with a high level of flexibility.

Unlike more abstract mathematical concepts, Bezier curves were created for industrial design. They are a popular tool in the graphics software industry.

They rely on interpolation, which we saw in the previous article, combining multiple steps to create smooth curves. To better understand how Bezier curves work, let's start from its simplest form: Quadratic Bezier.

Quadratic Bezier

Take three points, the minimum required for Quadratic Bezier to work:

../../_images/bezier_quadratic_points.png

To draw a curve between them, we first interpolate gradually over the two vertices of each of the two segments formed by the three points, using values ranging from 0 to 1. This gives us two points that move along the segments as we change the value of t from 0 to 1.

func _quadratic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, t: float):
    var q0 = p0.lerp(p1, t)
    var q1 = p1.lerp(p2, t)

We then interpolate q0 and q1 to obtain a single point r that moves along a curve.

var r = q0.lerp(q1, t)
return r

This type of curve is called a Quadratic Bezier curve.

../../_images/bezier_quadratic_points2.gif

(Image credit: Wikipedia)

Cubic Bezier

Building upon the previous example, we can get more control by interpolating between four points.

../../_images/bezier_cubic_points.png

We first use a function with four parameters to take four points as an input, p0, p1, p2 and p3:

func _cubic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2, t: float):

We apply a linear interpolation to each couple of points to reduce them to three:

var q0 = p0.lerp(p1, t)
var q1 = p1.lerp(p2, t)
var q2 = p2.lerp(p3, t)

We then take our three points and reduce them to two:

var r0 = q0.lerp(q1, t)
var r1 = q1.lerp(q2, t)