# Finding the Control Points of a Bezier Curve

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 Curve

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.

In the above image, P_{0} is the start point of the curve, P_{3} is the end point, and points P_{1} and P_{2} 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 P_{1} and P_{2}, you can change how much the curve, well, curves.

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

## How the Curve is Calculated

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 :).

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 = (P`

._{0} + P_{1}) / 2

The calculation first determines the midpoint of the start point Z_{0} and the first control point C_{0}, which gives us M_{0}. It then finds the midpoint of both control points C_{0} and C_{1}, which gives us M_{1}. Then it finds the midpoint of M_{0} and M_{1} giving us M_{3}, 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.

## Finding the Control Points

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 M_{5} (the midpoint of the curve) lies on the same horizontal line as M_{3}. You may have also noticed that M_{3} appears to be on the same horizontal line as the midpoint of M_{0} and C_{0}. A quick calculation confirms this as C_{0} and M_{1} lie on the same horizontal line, their Y values are the same. Thus the midpoint of M_{0} and C_{0} and M_{0} and M_{1} will have the same Y value.

Knowing this, we can see that the Y value of M_{3} and M_{5 }is 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)P`

, where _{0} + (t)P_{1}`t`

is the percentage along the line the point lies and `P`

is the start point and _{0}`P`

is the end point._{1}

Knowing this, we can now solve for the unknown control point. We know P_{0} (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 P_{1} (the unknown end point), we get: `P`

. We can now plug in the Y value of our start point for _{1} = (P - (1 - t)P_{0}) / t`P`

, the Y value of the midpoint for _{0}`P`

, and 3/4 for `t`

, and this will give us the Y value of where the control point should be placed!

## Example

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 `P`

, which is equal to 9._{1} = (7 - (1 - .75)) / .75

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

## Conclusion

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.