1 /*==============================================================================
2 
3  Copyright 2018 by Roland Rabien, Devin Lane
4  For more information visit www.rabiensoftware.com
5 
6  ==============================================================================*/
7 
8 #pragma once
9 #include <vector>
10 
11 /** Cubic spline interpolation is a simple way to obtain a smooth curve from a set of
12  discrete points. It has both C1 (first derivative) and C2 (second derivative) continuity,
13  enabling it to produce a continuous piecewise function given a set of data points.
14 
15  Add points in increasing x order */
16 class Spline
17 {
18 public:
19     void setup (const float *pointsX, const float *pointsY, int numPoints);
20 
21     double interpolate (double x) const noexcept;
22     int findElement (double x) const noexcept;
countElements()23     int countElements () const noexcept { return int (elements.size ()); }
24 
getX(int i)25     double getX (int i) const noexcept { return elements[i].getX (); }
getY(int i)26     double getY (int i) const noexcept { return elements[i].getY (); }
27 
28     class Element
29     {
30     public:
x(x_)31         Element (double x_ = 0) : x (x_) {}
32 
Element(double x_,double a_,double b_,double c_,double d_)33         Element (double x_, double a_, double b_, double c_, double d_)
34           : x (x_), a (a_), b (b_), c (c_), d (d_) {}
35 
getX()36         double getX () const noexcept { return x; }
getY()37         double getY () const noexcept { return a; }
38 
eval(double xx)39         double eval (double xx) const noexcept
40         {
41             double xix (xx - x);
42             return a + b * xix + c * (xix * xix) + d * (xix * xix * xix);
43         }
44 
45         bool operator< (const Element& e) const noexcept { return x < e.x;   }
46         bool operator< (const double xx) const noexcept  { return x < xx;    }
47 
48         double x = 0, a = 0, b = 0, c = 0, d = 0;
49     };
50 
51 private:
52     std::vector<Element> elements;
53 };
54