Finding the Control Points of a Bezier Curve

How a Bezier Curve is calculated taken from stackoverflow.com

I had an interesting problem while working on a web application using the Canvas to draw Bezier Curves. I had to find the two control points required to draw the curve when I only knew the start point, end point, and one other point on the curve. I couldn’t find anything on the internet so I thought I’d write an article on my findings.


Update September 16, 2014: While working on another project, I ran into the definitive way for finding the control points of a curve. I was looking into Chart.js and noticed that they used bezier curves between their data points in their line graph. I took at a look at their source code and found that they use a function to determine the curve between two points. They reference an article by Rob Spencer at scaled innovation for figuring out how to spline (curve) between points. My technique may have worked for my case, but this technique should work in most, if not all, cases.

This article is probably now deprecated in favor of this technique, but I’ll leave it’s content here for historical purposes.

Bezier Curves are very common in programming. They are used in graphics to create scalable vector graphics of curves, allowing the curve to remain smooth when scaled. When using the HTML5 Canvas, they are commonly used to draw ellipses. This was exactly what I was trying to do.

I needed to draw a curve that started and stopped at fixed points, and which passed through a fixed midpoint The problem was that to draw a Bezier Curve, you must know four points: the start point, the end point, and two other points called the control points.

A Bezier Curve using two control points from wikipedia

In the above image, P0 is the start point of the curve, P3 is the end point, and points P1 and P2 are the control points. As you can see, the curve does not pass through the control points. Instead, the control points are used to control the curve. By adjusting P1 and P2, you can change how much the curve, well, curves.

To see a working example of this, check out this online demo.

Before I get to the solution to the problem, I need to mention how the curve is calculated. There’s a great YouTube video about it which I recommend watching. A word of warning: The remainder of this tutorial uses some math concepts. You have been warned :).

[youtube=http://www.youtube.com/watch?v=YATikPP2q70&w=600&h=385]

Basically, a Bezier Curve is drawn by calculating the distance between the start point and the control points according to the percentage long it’s path. For example, the below image shows the points used to calculate the midpoint of the curve. As a refresher, the formula for finding the midpoint of two points is a follows: M = (P0 + P1) / 2.

How a Bezier Curve is calculated taken from stackoverflow.com

The calculation first determines the midpoint of the start point Z0 and the first control point C0, which gives us M0. It then finds the midpoint of both control points C0 and C1, which gives us M1. Then it finds the midpoint of M0 and M1 giving us M3, repeating this same process for each of the four points until the last midpoint is the midpoint of the curve. I can’t explain it nearly as well as the YouTube video, so please watch it for a better understanding.

Now that you understand how a Bezier Curve is calculated, you are now able to find how to calculate the control points if you only know the start point, end point, and one other point on the curve. In this specific case, I will be discussing how to obtain the control points when the other known point is the midpoint of the curve.

If you look at the picture of how to calculate the curve again, you may have noticed that point M5 (the midpoint of the curve) lies on the same horizontal line as M3. You may have also noticed that M3 appears to be on the same horizontal line as the midpoint of M0 and C0. A quick calculation confirms this as C0 and M1 lie on the same horizontal line, their Y values are the same. Thus the midpoint of M0 and C0 and M0 and M1 will have the same Y value.

Knowing this, we can see that the Y value of M3 and Mis the same as the midpoint of the midpoint of the start point and the control point. In other words, the Y value of the midpoint of the curve lies 3/4ths above the Y value of the start point. How does this help us?

It turns out there’s a very handy formula for finding the value of any point along a line. The YouTube video explains this formula, but I’ll restate it here. To find any point P along a line, use the formula: P = (1-t)P0 + (t)P1, where t is the percentage along the line the point lies and P0 is the start point and P1 is the end point.

Knowing this, we can now solve for the unknown control point. We know P0 (the start point), P (the point along the line), and t (the percentage along the line the point lies). If we rewrite the formula to find P1 (the unknown end point), we  get: P1 = (P - (1 - t)P0) / t. We can now plug in the Y value of our start point for P0, the Y value of the midpoint for P, and 3/4 for t, and this will give us the Y value of where the control point should be placed!

As a quick demonstration, lets say your starting point of the curve lies on at the point (1,1) and the midpoint lies at the point (1,7). Since we want the Y value of the control point, we will use the Y value of the points for the calculation. This gives us the equation P1 = (7 - (1 - .75)) / .75, which is equal to 9.

Therefore, our control point should line at the Y value of 9.

This equation only works for finding how far above the point the control point should be located. This is because if you were to change the X value of the control point it would only change how much the curve bows, but it would still pass through the midpoint

Finding the control points of a Bezier Curve can be a difficult task. However, if you do know the start point, then end point, and midpoint of the curve, it is possible to calculate the control points. I don’t know if this equation works for all values of t, if someone would like to confirm this that would be great! Just leave me a comment.