\( \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\Choose}[2]{ { { #1 }\choose{ #2 } } } \newcommand{\vecII}[2]{\left[\begin{array}{c} #1\\#2 \end{array}\right]} \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\matIIxII}[4]{\left[ \begin{array}{cc} #1 & #2 \\ #3 & #4 \end{array}\right]} \newcommand{\matIIIxIII}[9]{\left[ \begin{array}{ccc} #1 & #2 & #3 \\ #4 & #5 & #6 \\ #7 & #8 & #9 \end{array}\right]} \)

CS307: Bezier Curves

Plan

  • Bezier curves & blending functions
  • Bezier curves in Three.js
  • Exercises: Heart, ribbon, and double ribbons
  • Thought exercises: Coke bottle & circle

Bezier Curves & Blending Functions

In computer graphics, we often need to model objects whose shape is defined by free-form curves:

bridge   bezier   cat   luxo

One of the most popular approaches to modelling such shapes uses Bezier curves — let's first explore the basic ideas with this online tool.

We will represent a parametric curve P(t) as a weighted sum of four control points, P0, P1, P2, P3: \begin{eqnarray*} P(t) &=& B_0(t)*P_0 + B_1(t)*P_1 + B_2(t)*P_2 + B_3(t)*P_3 \end{eqnarray*}

For each value of t, the weights are given by four blending functions B0(t), B1(t), B2(t), B3(t).

This figure from the reading shows the four blending functions for cubic Bezier curves:

The blending functions for Bézier curves.
The blending functions for Bézier curves.

The equations for these functions, which are from the family of Bernstein polynomials, are shown in this plot in WolframAlpha:

plot (1-t)^3,3t(1-t)^2,3t^2(1-t),t^3 from t=0 to 1: all of them in one plot

Observations:

  • The first and last blending functions are monotonic
  • The functions are always non-negative
  • The functions sum to one
  • The second and third functions peak at 1/3 and 2/3

The Bezier curve is always within the convex hull of the control points.

Bezier Curves in Three.js

We'll start with this demo of an S curve:

S curve

The code for this demo is quite short:

var controlPoints = [ [0,0,0],
                      [2,2,0],
                      [-2,1,0],
                      [0,3,0] ];
var curveGeom = TW.createBezierCurve(controlPoints,20);
var curveMat = new THREE.LineBasicMaterial( { color: 0xff,
                                              linewidth: 3 } );
var curve = new THREE.Line( curveGeom, curveMat );
scene.add(curve);

function showCP (cpList) {
    for( var i = 0; i < cpList.length; i++ ) {
        scene.add( TW.createPoint(cpList[i]) );
    }
};

showCP(controlPoints);          // optional, for debugging

This code depends on two functions in TW, which just make our lives a little easier. The first is TW.createBezierCurve():

 

The above function creates a THREE.CubicBezierCurve3.

The second function, TW.createPoint(), is just a minor convenience:

 

To understand the role of the control points, let's play with the curve using a GUI:

S curve with a GUI

(You can also play with this online Bezier curve demo, which allows you to drag the control points with your mouse and view their coordinates. To map your results onto the above Three.js demo, place the control points within a box whose X and Y coordinates range from -5 to +5.)

  • What is the result of moving P1 farther from or nearer to P0 without changing the direction?
  • How is the convex hull related to the curve?
  • How many bends can you get in the curves?
  • How tight a loop can you get? Can you get this?

    bezier chevron

The following demo illustrates a 3D Bezier curve:

S curve in 3D

Exercises: Creating 2D Shapes from Bezier Curves

For each of the following exercises, use this S curve code file as a starting point to create the desired shape.

Heart

Devise the control points to draw a heart, like this:

heart outline

Implement the result, using this S curve as a starting point.
Hint: This requires two Bezier curves.

The result might look like this:   heart curve

Here are two solutions with control points shown as spheres:
heart2.html    heart3.html   

Ribbon

Devise the control points to draw a ribbon, like this:

one ribbon

Implement the result, using this S curve as a starting point.

The result might look like this:   ribbon curve

Double Ribbons

Devise the sets of control points to draw a joined double ribbon, like this:

two ribbons

Implement the result, using this S curve as a starting point. How many Bezier curves do you need in this case?

The result might look like this:   double ribbon curve

Coke Bottle

Here's a thought experiment: How would you draw the silhouette of a Coketm bottle?

Coke bottle silhouette

Circles

Can you do a circle? How or why not?