I recently had to research methods to draw curves through a set of points. While interpolation wasn’t the most appropriate and efficient approach in my case, I still had some fun with the Accelerate framework (which optimizes large-scale mathematical computations).
1. What is an interpolation?
In the mathematical field of numerical analysis, interpolation is a type of estimation, a method of constructing new data points within the range of a discrete set of known data points. (Sheppard, William Fleetwood)
For instance, let’s say you’re eating delicious pasta. Your plate contains 20 gnocchi, and you eat them continuously in a 10 min period of time. While the scenario can be managed by head ([0, 2, 4, …, 18, 20]), it’s a task that interpolation algorithms can easily achieve, whatever the numbers.
2. Examples to interpolate using Accelerate framework
Besides implementing the logic in simple Swift code, you can directly use the Accelerate framework which should fasten the process!
2.1 Simple interpolation (Gnocchi)
So let’s say we want to interpolate how the 20 gnocchi are eaten within the 10 minutes timeframe, we could write:
The output should be
[0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0], meaning that at minute 2, 4 gnocchi should be gone.
More information about this “basic” linear interpolation in the documentation.
2.2 Complex interpolation (CGPoint)
The previous code works fine with values that follow on another (e.g.
[1, 2, 3]). But what about more complex inputs as set of CGPoints where y axis values go up and down? (e.g.
[(x: 1, y: 1.5), (x: 2, y: 5.0), (x: 3, y: 3.5)]).
We could directly dive into a CGPoint example, but we’ll cover this part in the next section. For now, let’s focus on the “y” value which requires interpolation (in the case your curve is horizontal).
stepsis the length of the output (number of interpolation points).
strideholds differences between indices of elements (our x axis for CGPoint).
valuesholds the y value of our CGPoints (as it’ll be an horizontal alignment).
controlholds the fractional part to interpolate between the values.
resultholds the output of the linear interpolation.
3. CGPoint extension for linear interpolation
Our input vector isn’t compatible with CGPoints: we have to take care of the intermediate logic ourselves.
If you want to directly read the extension code, check this file.
Let’s create a CGPoint extension:
- Depending on the graph direction, we should use either x or y axis.
- The number of interpolated points should be dynamic.
- And let’s allow a switch between linear and quadratic interpolation.
There are two additional steps compared to the previous code:
- Extract the “values” from the CGPoint list.
- Construct the new CGPoint list based on the interpolation output.
Let’s put our extension inside a new file called
As mentionned above, we plan to a/ handle both horizontal and vertical cases, and b/ handle the linear and quadratic interpolations. For this purpose, let’s create two ENUMs:
Let’s keep the extension method simple:
Extracting the input vector from our CGPoint list isn’t difficult.
However, constructing the output requires more lines as we add data instead of removing some.
Then you merge this with the logic we wrote a bit earlier, and voilà.
4. Wrapping the fun inside a SwiftUI project
I spent some time having fun with SwiftUI. You can download the Xcode project and play with it. Check the animation below as a small demo.
- The red points are randomly generated.
- The blue points are generated from the interpolation.
- The blue line is drawn from the interpolation points.
- You can switch between linear and quadratic algorithm.
Special thanks to Axel Le Pennec for mentioning the interpolation (Accelerate) methods to me.
LastMod 14 January, 2021