# Understanding Quadratic Bézier Curves

In a client project I had to draw by hand a quadratic Bézier curve, because the html5 canvas quadraticCurveTo does not return the information about the path drawn and I needed it.

Some basic explanation of a quadratic Bézier curve. You have a
start point `P1`

, an end point `P2`

and a control point `C`

. Both the `x`

and
`y`

of each point on the path is dependant on `t`

, which will vary from
0 to 1. `t=0`

at the begining of the curve and `t=1`

and the end of the curve.

You draw an imaginary line between `P1`

and `C`

(`P1C`

line) and
another one between `C`

and `P2`

(`CP2`

line). For each value of `t`

, you mark
an imaginary point on `P1C`

and `CP2`

. The point on `P1C`

is at `t`

of the line,
starting at `P1`

, and the point on the `CP2`

line is at `t`

of the line,
starting at `C`

. Let's call those points `C1`

and `C2`

.

Then, you draw an imaginary line between `C1`

and `C2`

, and you mark a real
point at `t`

of the `C1C2`

line.

You repeat the procedure for every value of `t`

, where `t`

varies from 0 to 1.
All the points you marked on the line `C1C2`

are showing the quadratic Bézier
curve.

Here's a little animation I made to explain it better:

t = 0

You can have a look at the source for a complete understanding, but here's the important part, edited for clarity:

// constants

var CANVAS_WIDTH = 301;

var CANVAS_HEIGHT = 301;

var p1x = 20;

var p1y = 200;

var cx = 140;

var cy = 20;

var p2x = 280;

var p2y = 280;

// basic setup

var $t = $('#bezier-example-1-t span');

var animationCanvas = $('#bezier-example-1 .animation').get(0);

var animationContext = animationCanvas.getContext('2d');

animationCanvas.width = CANVAS_WIDTH;

animationCanvas.height = CANVAS_HEIGHT;

var curveCanvas = $('#bezier-example-1 .curve').get(0);

var curveContext = curveCanvas.getContext('2d');

curveCanvas.width = CANVAS_WIDTH;

curveCanvas.height = CANVAS_HEIGHT;

curveContext.strokeStyle = "#777";

curveContext.lineWidth = 2;

curveContext.beginPath();

curveContext.moveTo(p1x, p1y);

curveContext.stroke();

setInterval(updateDemo, 1000/30);

var t = 0;

var d = 1; // direction

function updateDemo() { // called 30 times/second to animate

if (t > 1 || t < 0) {

d *= -1; // change direction

curveContext.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

curveContext.beginPath();

}

t += 0.01 * d; // continue moving

$t.html(Math.round(t*100)/100);

// update values

var c1x = p1x + (cx - p1x) * t;

var c1y = p1y + (cy - p1y) * t;

var c2x = cx + (p2x - cx) * t;

var c2y = cy + (p2y - cy) * t;

var tx = c1x + (c2x - c1x) * t;

var ty = c1y + (c2y - c1y) * t;

animationContext.save();

// clear old sketch

animationContext.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

// draw new line

animationContext.beginPath();

animationContext.strokeStyle = '#aaa';

animationContext.lineWidth = 1;

animationContext.moveTo(c1x, c1y);

animationContext.lineTo(c2x, c2y);

animationContext.stroke();

// draw points on lines

drawPoint(animationContext, c1x, c1y, 2, '#0f0');

drawPoint(animationContext, c2x, c2y, 2, '#0f0');

// draw point on curve

drawPoint(animationContext, tx, ty, 3, '#f0f');

animationContext.restore();

// draw the new Bezier curve segment

curveContext.lineTo(tx, ty);

curveContext.stroke();

}

The code is on Github.