# Curve Fitting

17 Jul 2015Here is a simple technique to modify linear data points to a curve of your choice. If your function looks linear like this:

or even has an inverse linear form like this:

And you want to instead map it to a curve that accentuates the initial values and suppresses the tail:

or has an exponential drop at the end points like this:

then, Cubic Bezier curves can be used to achieve the desired transformation. A Cubic Bezier curve is given by:

B(t) = (1 - t)^{3}**P _{0}** + 3(1 -t)

^{2}t

**P**+ 3(1 -t)t

_{1}^{2}

**P**+ t

_{2}^{3}

**P**

_{3}Here P_{0}, P_{3} are the end-points of the curve and P_{1} and P_{2} are control points. A Cubic Bezier curve, at the starting point is always tangential to the line segment P_{0}, P_{1} and in the direction of P_{0}, P_{1}. At the endpoint, the curve is tangential to P_{2}, P_{3} and is in the direction of P_{2}, P_{3}. You can play around with various Cubic Beziers shapes at desmos.com.

When implementing a Cubic Bezier curve, the first oddity you will encounter is the fact that unlike polynomial equations, the Bezier does not give you y-coordinates as a function of x-coordinates. Instead, it independently gives you x and y coordinates as a function of a parameter t which varies from 0 to 1. When t = 0, the curve is at point P_{0} and when t = 1, the curve is at point P_{3}. Worse, when you vary t linearly, you do not get linear increments of x. Instead, you get linear increments along the curve’s length. In fact, it is this property of Bezier curves that makes them suitable as easing functions for animations. By constructive a Cubic Bezier with steep starting and ending slopes, you can get a slow start in the x axis followed by an acceleration in the middle and a gradual slowdown towards the end. But for mapping a traditional function of the form y = f(x), we would like to transform the Bezier to a similar function.

There is no simple mathematical way to achieve this given expressions like t^{2} and t^{3} in the equation. Instead, one can approximate a solution by doing a binary search along t, computing the corresponding x until we are within a tolerance limit. At that point, the value of y can be computed. The gist below shows a Java program to do that. In addition, the program allows you to pre-compute y = Bezier(x) for x = (start, end) in specified increments.

The class above can be extended to create a composite Cubic Bezier curve fitting algorithm that combines multiple Cubic Bezier curves to model any shape you want to create.