This is a guest post from my friend Łukasz Izdebski Ph.D.
Intro
It’s been a while since my last guest post on Adam’s blog, but I’m back with something short and practical—think of it as an epilogue to this earlier post on Bézier curves in animation. The last post focused on the theory and mathematics behind Bézier curves. What it lacked was a practical perspective—an opportunity to see the implementation in action. I wanted to share with you a simple library that I have created. Its purpose is to directly represent cubic Bézier Curves as Easing Functions.
Library
The library is designed with C++20 and newer standards in mind, taking advantage of modern language features for clarity and performance. If needed, support for earlier versions of C++ can be added to ensure broader compatibility.
Self-contained C++ library in single header file. No external dependencies other than standard C and C++ library.
The entire concept is encapsulated in a single template class: EasingCubicBezier . This class handles the interpolation of parameters used in the keyframe method. The interpolation of parameters follows the same principles as standard Bézier curve evaluation.
. This class handles the interpolation of parameters used in the keyframe method. The interpolation of parameters follows the same principles as standard Bézier curve evaluation. The constructor takes the X and Y coordinates of the 4 control points of the cubic Bézier curve.
Once instantiated, you can call the evaluate function with a parameter t , which should lie between x0 (the X coordinate of the first control point, representing the start time of the frame) and x3 (the X coordinate of the fourth control point, representing the end time).
function with a parameter , which should lie between x0 (the X coordinate of the first control point, representing the start time of the frame) and x3 (the X coordinate of the fourth control point, representing the end time). The function returns the interpolated value at time t, based on the shape of the Bézier curve.
The library can be used in two modes: PRECISE – uses transcendental and irrational functions implemented in the library, ensuring high accuracy. FAST – uses fast approximations for selected transcendental and irrational functions, allowing for better performance at the expense of precision.
Platform-independent, but developed and tested on Windows using Visual Studio and was tested in Linux using Clang.
Testing the library
As presented in previous blog post, the EasingCubicBezier character as a easing function depends solely on the X coordinates of the control points. The tests were prepared for a single, fixed value of the Y coordinates of the Bézier curve control points (their value does not affect the interpolation performance in any way), and for a set of 256 different variants of the X coordinates of the control points. The aim was to cover as wide a range of control point locations as possible (in particular, the two inner points).
Performance measurements were carried out using the Google Benchmark framework, ensuring reliable and consistent results. Further details and test results are available in the library repository.
Tested algorithms
The new approach using EasingCubicBezier has been benchmarked against two commonly used methods in game engines and graphics applications. Both of these alternatives rely on solving cubic polynomial equations, either through algebraic solutions or numerical techniques. In the case of numerical methods, a critical factor is the choice of the initial starting point. This selection plays a major role in determining the algorithm’s convergence speed and stability.
The following tests compared 5 different algorithms:
Easing Cubic Bezier – The new approach. Original Blender – The algebraic method used in Blender, which solves cubic equations analytically. Optimised Blender – A slightly refined version of Blender’s algorithm with performance improvements. Numeric Solution 1 – Newton-Raphson method with a starting point of 0.5 (because the X coordinates of the curve were previously normalised to the interval [0, 1] ). Numeric Solution 2 – Newton-Raphson method with a starting point equal to the value t , where t is the input parameter for which the Bézier curve interpolation is being evaluated.
Test results
The chart and the table below presents the benchmark results using a box plot, highlighting the distribution and variability of each algorithm’s performance in PRECISE mode with AVX2 extensions turned On.
Algorithm Min Q1 Median Q3 Max Average Std dev Easing Cubic Bezier 1562.5 21875.0 32812.5 32812.5 39062.5 28991.7 7803.5 Numeric Solution 1 7812.5 17187.5 23437.5 53515.6 150000.0 40856.9 32900.5 Numeric Solution 2 4687.5 15625.0 21093.8 52343.8 173438.0 37292.5 31220.9 Original Blender 40625.0 54687.5 56250.0 56250.0 60937.5 55096.4 2659.2 Optimised Blender 12500.0 40625.0 42187.5 43750.0 45312.5 41003.4 5931.3
The chart and the table below presents the benchmark results using a box plot, highlighting the distribution and variability of each algorithm’s performance in FAST mode mode with AVX2 extensions turned On.
Algorithm Min Q1 Median Q3 Max Average Std dev Easing Cubic Bezier 3125.0 15625.0 21875.0 23437.5 23437.5 19714.4 4838.2 Numeric Solution 1 7812.5 17187.5 23437.5 59375.0 331250.0 42059.3 37539.5 Numeric Solution 2 4687.5 15625.0 20312.5 48437.5 156250.0 36926.3 31357.5 Original Blender 32812.5 44921.9 50000.0 50000.0 50000.0 47418.2 3817.4 Optimised Blender 12500.0 35937.5 42187.5 42187.5 43750.0 39953.6 5554.2
Conclusions
The table below summarizes the key conclusions drawn from the benchmark tests.
Algorithm Performance Variation Conclusions Easing Cubic Bezier Very stable and consistently low execution time Minimal Most predictable and effective in typical use cases Numeric Solution 1 Highly variable — ranging from excellent to extremely slow Huge, with many outliers Efficient in some cases, but unstable and prone to severe slowdowns Numeric Solution 2 Similar to Numeric Solution 1, but with more symmetrical behavior Large, but less extreme More balanced overall, though still susceptible to performance issues Original Blender High execution time Very small Stable and predictable; useful when consistency is more important than speed Optimised Blender Moderate execution time Small A good compromise between speed and stability
Why Should You Use This Library?
By representing Bézier curves explicitly in just 28 bytes ( float ) or 56 bytes ( double ) using the proposed method, this approach delivers both speed and stability—making it ideal for real-time animation systems. By storing the curve in this form, runtime execution becomes straightforward: it directly interpolates parameter values without the need to solve cubic polynomial equations.This eliminates the overhead typically associated with solving cubic polynomials during runtime. The cost of determining the interpolating function corresponding to a given Bézier curve is deferred to the construction of an EasingCubicBezier object. Moreover, constructor has been optimized to minimize overhead.
This is just the beginning of my journey with easing functions. I am working on another solution, whose main goal will be maximum performance in runtime, while maintaining flexibility comparable to that offered by cubic Bézier curves.
Stay tuned!
Comments | #math #rendering Share
Comments
Please enable JavaScript to view the comments powered by Disqus.