Smooth Bezier splines

Apparently, having mathematically defined curves that pass through a set of desired points is a thing. And (cubic) Bezier splines are popular for this. Professor Dagan (mentioned previously) sent me a link.

Smooth B├ęzier Spline Through Prescribed Points

The article outlines a method that given a set of points you want your Bezier curve to pass through, calculate the required control points of the Bezier curve. This is similar to what I wrote here.

The difference is that my method requires the inverse of the coefficient matrix to exist, which it does. The method in that article requires the first and second derivatives of the Bezier curve to be continuous.

Cubic polynomials and cubic Beziers

So it turns out that for cubic Bezier curves, t values of 0, 1/3, 2/3 and 1 have special meanings. A general cubic polynomial is of the form

y = a0 + a1 * x + a2 * x^2 + a3 * x^3

where ai’s are real constants.

If the variable x is limited to the interval x0 <= x <= x0 + χ (that's the Greek letter Chi), where χ > 0, then it’s equivalent to a special case of cubic Bezier curves. Namely, when the t values are 0, 1/3, 2/3 and 1.

In fact, there’s a mathematical proof of it. Thanks to Professor Samuel Dagan of Tel-Aviv University for writing in and letting me know of his work. Here’s more of his work.

Does the point lie on the Bezier curve?

Someone recently asked me how to tell if a point lies on a Bezier curve.

For the purposes of discussion, it’s a quadratic Bezier curve and all 3 control points are known (or the start and end points and the 1 control point if you prefer). You can read more about the reverse process of finding the control points here, which is the reference point of that person’s question.

The answer is actually straightforward. Substitute everything into the Bezier curve equation and solve for t. Here’s the quadratic Bezier equation:
B(t) = (1-t)^2 * p0 + 2(1-t)t * p1 + t^2 * p2

Let’s say p0 is [1,1] and p1 is [1.5,4.5] and p2 is [2,3]. We’ll keep the points in 2 dimensions to keep the maths working less cumbersome. And let’s say the point you want to check is [1.8,3.4]. We substitute all the points into the equation, and we get this:

[1.8,3.4] = (1-t)^2 * [1,1] + 2(1-t)t * [1.5,4.5] + t^2 * [2,3]

I know, it doesn’t look pretty. But hey, we’re doing this by hand. If you’re writing code to generalise the solution, the code will probably look just a little uglier, but the solution will come out faster. Like probably instantly given the current modern processors.

Because we’re dealing with 2 dimensional points, that equation splits into 2 separate equations (with scalars instead of vectors as coefficients), like so:
1.8 = (1-t)^2 * 1 + 2(1-t)t * 1.5 + t^2 * 2
3.4 = (1-t)^2 * 1 + 2(1-t)t * 4.5 + t^2 * 3

If you have 3 dimensional points, you’d have 3 equations. Note that even then, the degree of your equations remains as 2. The degree of the Bezier curve is independent of the number of dimensions you’re working with.

If you simplify
1.8 = (1-t)^2 * 1 + 2(1-t)t * 1.5 + t^2 * 2

You get t = 0.8. It so happens that in this case, there’s only one solution.

If you simplify
3.4 = (1-t)^2 * 1 + 2(1-t)t * 4.5 + t^2 * 3

You get
5*t^2 – 7*t + 2.4 = 0

and after solving for that, you get t = 0.6 or t = 0.8 (you’re a smart person, you know how to solve a quadratic equation, right?)

Now, the solution t=0.8 appears in the solution sets of both equations. Therefore, the point [1.8,3.4] lies on the Bezier curve. In fact, t=0.8 is the t value.

Multiple solutions

What if you get multiple t values appearing in multiple solution sets of equations?

Consider the case where p0 is [1,1], p1 is [2,3], and p2 is [1,1]. Notice that the start and end points are the same point. Let’s say you want to know if the point [1,1] lies on the curve (yes I know it’s the same point). Substituting all the points, we get:

[1,1] = (1-t)^2 * [1,1] + 2(1-t)t * [2,3] + t^2 * [1,1]

This gives us the 2 equations:
1 = 1 – 2*t + t^2 + 4*t – 4*t^2 + t^2
1 = 1 – 2*t + t^2 + 6*t – 6*t^2 + t^2

They simplify to:
2*t^2 – 2*t = 0
4*t^2 – 4*t = 0

Hey presto! The solution set is t=0 or t=1 for both equations. Therefore, the point [1,1] lies on the curve. In fact, it lies on the curve where t=0 or t=1. And t=0 and t=1 happens to coincide with the start and end points respectively.

The whole point (haha!) is that, as long as you have at least one value of t that appears in the solution sets of all the equations, then said point you’re checking lies on the curve.

Higher degree Bezier curves

This is a toughie. If you have a cubic Bezier curve, then you’re solving a degree 3 polynomial (of t). If you have a Bezier curve of degree N, then you’re solving a degree N polynomial.

There are algorithms to solve generic degree polynomials, but they are out of scope here. Assuming the highest degree of Bezier curves you’ll ever work with is 3 (cubic), then this Wikipedia article on cubic functions will help. Remember, cubic Bezier curve equations are still cubic equations.

Higher dimensionality

The number of dimensions you’re working with determines the number of equations you need to solve. If you’re working with 5 dimensional points, then you need to solve for 5 equations.

For example, if you’re working with cubic Bezier curves and using 5 dimensional points, then you need to solve 5 cubic functions. You will have possibly 3 (unique) t values for each equation. Let’s say your solution sets are as follows:
t = -1, 3, 5
t = 0, 1, 3
t = -2, 2, 3
t = 3, 3, 4 (yay repeated values!)
t = 3, 6, 8

The value t=3 appears in all 5 sets of solutions, therefore your point lies on the curve.

Keep it real

In the process of solving your equations, there’s a possibility that you might get imaginary solutions. You know, those involving the square root of -1. Dismiss them.

Your Bezier curve is in the real world. The point you’re checking must therefore also lie in the real world.

Unless you’re working with some abstract imaginary Bezier curves on an advanced maths paper. Then good luck to you! The logic above for solving still applies.

Actual applications

When applying the above, you don’t usually get nice numbers like [1.8,3.4] lying on the curve with t=0.8. You get numbers with lots of numbers behind the decimal point that seems to continue forever. You don’t get exact values.

What if you get a t=0.798 for one equation, and t=0.802 for another equation?

Use your common sense. Set an error margin for what is acceptable.

My suggestion is to NOT use the values of t to check for the margin. Substitute the values of t into the equation, and then check the points if they’re within the error margin.

This means you don’t check the difference between t=0.798 and t=0.802, which is 0.04. Is 0.04 within your error margin? Maybe. But you’re not checking for this.

You substitute t=0.798 and t=0.802 into the equation, and you get 2 points: [1.798,3.40198] and [1.802,3.39798]

Then you say, “Are these points close enough that I consider them to be the same point?” Use whatever you think is appropriate. I think the Euclidean distance norm works fine. Then check if that “close enough” criteria is within your error margin.

If you’re checking for [1.8,3.4], then ask yourself, “Is [1.8,3.4] close enough to [1.798,3.40198]? And is [1.8,3.4] close enough to [1.802,3.39798]?”

Obviously, doing this by hand sucks big time. Good thing you’re a programmer.

Quadratic Bezier curve control point calculation demo

MacGile made a video to demonstrate the calculation of control points of a quadratic Bezier curve. The algorithm is based on what I wrote here.

That looks awesome! Thanks MacGile!

Bezier curves prefer tea

My maths professor was hammering on the fact that Citroen used Bezier curves to make sure their cars have aesthetically pleasing curves. Again. (This is not a sponsored post from the automaker).

While I appreciate his effort in trying to make what I’m learning relevant to the real world, I kinda got the idea that Citroen used Bezier curves in their design process. Right about the 3rd tutorial lesson.

My professor then went on to give us homework. “Us” meaning 5 of us. It was an honours degree course. It wasn’t like there was a stampede to take post-graduate advanced maths lessons, you know.

Oh yes, homework. My professor, with wisdom acquired over years of teaching, gave a blend of theoretical and calculation-based questions. Any question that had the words “prove”, “justify”, “show” are probably theoretical questions. Calculation-based questions are like “What is 1 + 1?”. Everyone, at least theoretically (haha!), should be able to do the calculation-based questions. The theoretical questions would require more thinking (“Prove that such and such Bezier curve is actually equal to such and such.”).

My friend, who took the course with me, loved calculation-based questions. She’d sit patiently and hammer at the numbers and the calculator. I can’t say I love them. My professor once gave a question that amounted to solving a system of 5 linear equations with 5 unknowns, which amounted to solving a 5 by 5 matrix. By hand. (It involves 15 divisions, 50 multiplications and 50 subtractions. There’s a reason why linear algebra and numerical methods were pre-requisites) I wanted to scream in frustration, throw my foolscap paper at him, and strangle him. Not necessarily in that order.

This coming from someone who is fine with writing a C program doing memory allocations (using the malloc function. And then manually freeing the pointer with the memory allocation. We didn’t have garbage collection, ok?) to simulate an N-sized matrix, and then perform Gauss-Jordan elimination on the matrix. I used that program to solve a 100 by 100 matrix. But I dreaded solving a 5 by 5 matrix by hand.

It probably explains why I remember Bezier curves so much.

Anyway, a while ago, someone sent me a question (through Facebook, of all channels). He asked, for a given “y” value of a Bezier curve, how do you find the “x” value?

That is a question without a simple answer. The answer is, there’s no guarantee there’s only one “x” value. A cubic Bezier curve has a possibility of having 1, 2 or 3 “x” values (given a “y”). Here’s the “worst” case scenario:

Multi x values

So you can have at most 3 “x” values. In the case of the person who asked the question, this is not just wrong, but actually dangerous. The person was an engineer, working on software that cuts metal (or wood). The software had a Bezier curve in it, which it used to calculate (x,y) coordinate values to direct the laser beam (or whatever cutting tool) to the next point (and thus cut the material).

If a “y” value has multiple “x” values, the software won’t know which “x” value you want. And thus cut the material wrongly.

The only way a Bezier curve has only 1 value, is if it’s monotonically increasing/decreasing. That means for all values of x and y such that x <= y [or x >= y], that f(x) <= f(y) [or f(x) >= f(y)].

Bezier curves don’t work well in the Cartesian plane. They work fine after you’ve used them to calculate values, and then transfer onto the Cartesian plane. Bezier curves prefer to work with values of t.