52 #ifndef __PCL_CubicSplineInterpolation_h
53 #define __PCL_CubicSplineInterpolation_h
58 #include <pcl/Diagnostics.h>
80 template <
typename T =
double>
160 void Initialize(
const vector_type& x,
const vector_type& y )
override
162 if ( y.Length() < 2 )
163 throw Error(
"CubicSplineInterpolation::Initialize(): Less than two data points specified." );
170 int n = this->Length();
180 if ( m_dy1 == 0 && m_dyn == 0 )
185 m_dy2[0] = m_dy2[n-1] = w[0] = 0;
187 for (
int i = 1; i < n-1; ++i )
189 double s = (double( m_x[i] ) - double( m_x[i-1] )) / (
double( m_x[i+1] ) - double( m_x[i-1] ));
190 double p = s*m_dy2[i-1] + 2;
191 m_dy2[i] = (s - 1)/p;
192 w[i] = (double( m_y[i+1] ) - double( m_y[i ] )) / (
double( m_x[i+1] ) - double( m_x[i ] ))
193 - (
double( m_y[i ] ) - double( m_y[i-1] )) / (
double( m_x[i ] ) - double( m_x[i-1] ));
194 w[i] = (6*w[i]/(double( m_x[i+1] ) - double( m_x[i-1] )) - s*w[i-1])/p;
197 for (
int i = n-2; i > 0; --i )
198 m_dy2[i] = m_dy2[i]*m_dy2[i+1] + w[i];
205 w[0] = 3/(double( m_x[1] ) - double( m_x[0] ))
206 * ((
double( m_y[1] ) -
double( m_y[0] ))/(double( m_x[1] ) - double( m_x[0] )) - m_dy1);
210 for (
int i = 1; i < n-1; ++i )
212 double s = (double( m_x[i] ) - double( m_x[i-1] )) / (
double( m_x[i+1] ) - double( m_x[i-1] ));
213 double p = s*m_dy2[i-1] + 2;
214 m_dy2[i] = (s - 1)/p;
215 w[i] = (double( m_y[i+1] ) - double( m_y[i ] )) / (
double( m_x[i+1] ) - double( m_x[i ] ))
216 - (
double( m_y[i ] ) - double( m_y[i-1] )) / (
double( m_x[i ] ) - double( m_x[i-1] ));
217 w[i] = (6*w[i]/(double( m_x[i+1] ) - double( m_x[i-1] )) - s*w[i-1])/p;
220 m_dy2[n-1] = (3/(double( m_x[n-1] ) - double( m_x[n-2] ))
221 * (m_dyn - (
double( m_y[n-1] ) -
double( m_y[n-2] ))/(double( m_x[n-1] ) - double( m_x[n-2] ))) - w[n-2]/2)
222 / (1 + m_dy2[n-2]/2);
224 for (
int i = n-2; i >= 0; --i )
225 m_dy2[i] = m_dy2[i]*m_dy2[i+1] + w[i];
234 m_dy2[0] = m_dy2[n-1] = w[0] = 0;
236 for (
int i = 1; i < n-1; ++i )
238 double p = m_dy2[i-1]/2 + 2;
240 w[i] = double( m_y[i+1] ) - 2*double( m_y[i] ) + double( m_y[i-1] );
241 w[i] = (3*w[i] - w[i-1]/2)/p;
244 for (
int i = n-2; i > 0; --i )
245 m_dy2[i] = m_dy2[i]*m_dy2[i+1] + w[i];
261 PCL_PRECONDITION( IsValid() )
263 int n = this->Length();
276 int j0 = m_current, j1;
277 if ( j0 < 0 || x < m_x[j0] || m_x[j0+1] < x )
278 for ( j0 = 0, j1 = n-1; j1-j0 > 1; )
280 int m = (j0 + j1) >> 1;
295 double h = double( m_x[j1] ) - double( m_x[j0] );
297 return 0.5*(double( m_y[j0] ) + double( m_y[j1] ));
299 double a = (double( m_x[j1] ) - x)/h;
300 double b = (x - double( m_x[j0] ))/h;
301 return a*double( m_y[j0] )
302 + b*double( m_y[j1] )
303 + ((a*a*a - a)*m_dy2[j0] + (b*b*b - b)*m_dy2[j1])*h*h/6;
314 return a*double( m_y[j0] )
315 + b*double( m_y[j1] )
316 + ((a*a*a - a)*m_dy2[j0] + (b*b*b - b)*m_dy2[j1])/6;
344 mutable int m_current = -1;
Generic interpolating cubic spline.
CubicSplineInterpolation()=default
double operator()(double x) const override
void SetBoundaryConditions(double y1, double yn)
void Initialize(const vector_type &x, const vector_type &y) override
CubicSplineInterpolation(CubicSplineInterpolation &&)=default
void GetBoundaryConditions(double &y1, double &yn) const
~CubicSplineInterpolation() override
CubicSplineInterpolation(const CubicSplineInterpolation &)=default
bool IsValid() const override
A simple exception with an associated error message.
Generic vector of arbitrary length.
A generic interface to one-dimensional interpolation algorithms.
virtual void Initialize(const vector_type &x, const vector_type &y)
int TruncInt(T x) noexcept
constexpr const T & Min(const T &a, const T &b) noexcept
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept