52 #ifndef __PCL_SurfacePolynomial_h
53 #define __PCL_SurfacePolynomial_h
58 #include <pcl/Diagnostics.h>
141 return !m_polynomial.IsEmpty();
167 PCL_PRECONDITION( degree >= 1 )
190 PCL_PRECONDITION( x !=
nullptr && y !=
nullptr && z !=
nullptr )
191 PCL_PRECONDITION( n > 2 )
194 throw Error(
"At least three input nodes are required in SurfacePolynomial::Initialize()" );
200 for (
int i = 0; i < n; ++i )
210 for (
int i = 0; i < n; ++i )
212 double dx = m_x0 - x[i];
213 double dy = m_y0 - y[i];
214 double r =
Sqrt( dx*dx + dy*dy );
219 throw Error(
"SurfacePolynomial::Initialize(): Empty or insignificant interpolation space" );
223 const int size = (m_degree + 1)*(m_degree + 2) >> 1;
230 for (
int i = 0; i < n; ++i )
232 X[i] = m_r0*(x[i] - m_x0);
233 Y[i] = m_r0*(y[i] - m_y0);
237 for (
int k = 0; k < n; ++k )
240 for (
int i = 0, l = 0; i <= m_degree; ++i )
241 for (
int j = 0; j <= m_degree-i; ++j, ++l )
242 Z[k][l] =
PowI( X[k], i ) *
PowI( Y[k], j );
246 for (
int i = 0; i < size; ++i )
248 for (
int j = 0; j < size; ++j )
250 for (
int k = 0; k < n; ++k )
251 M[i][j] += Z[k][i] * Z[k][j];
255 for (
int k = 0; k < n; ++k )
256 R[i] += z[k] * Z[k][i];
261 for (
int i = 0; i < size; ++i )
263 double pMi = M[i][i];
266 for (
int j = i; j < size; ++j )
271 for (
int k = 1; i+k < size; ++k )
273 double pMk = M[i+k][i];
274 if ( M[i+k][i] != 0 )
276 for (
int j = i; j < size; ++j )
279 M[i+k][j] -= M[i][j];
288 for (
int i = size; --i >= 0; )
290 m_polynomial[i] =
scalar( R[i] );
291 for (
int j = i; --j >= 0; )
292 R[j] -= M[j][i]*R[i];
300 T operator ()(
double x,
double y )
const
302 PCL_PRECONDITION( !m_polynomial.IsEmpty() )
304 double dx = m_r0*(x - m_x0);
305 double dy = m_r0*(y - m_y0);
308 for (
int i = 0, l = 0; ; px *= dx )
311 for (
int j = 0; j <= m_degree-i; py *= dy, ++j, ++l )
312 z += m_polynomial[l]*px*py;
313 if ( ++i > m_degree )
325 m_polynomial.Clear();
334 vector_type m_polynomial;
350 template <
class P = DPo
int>
395 Initialize( P1, P2, degree );
407 Initialize( Sx, Sy );
445 PCL_PRECONDITION( P1.
Length() >= 3 )
447 PCL_PRECONDITION( degree > 0 )
452 m_Sx.SetDegree( degree );
453 m_Sy.SetDegree( degree );
456 throw Error(
"PointSurfacePolynomial::Initialize(): At least three input nodes must be specified." );
459 throw Error(
"PointSurfacePolynomial::Initialize(): Incompatible point array lengths." );
465 for (
int i = 0; i < X.Length(); ++i )
472 m_Sx.Initialize( X.Begin(), Y.Begin(), Zx.Begin(), X.Length() );
473 m_Sy.Initialize( X.Begin(), Y.Begin(), Zy.
Begin(), X.Length() );
492 return m_Sx.IsValid() && m_Sy.IsValid();
516 template <
typename T>
519 return DPoint( m_Sx( x, y ), m_Sy( x, y ) );
525 template <
typename T>
528 return operator ()( p.
x, p.
y );
size_type Length() const noexcept
A simple exception with an associated error message.
Generic dynamic matrix of arbitrary dimensions.
A generic point in the two-dimensional space.
component x
Abscissa (horizontal, or X-axis coordinate).
component y
Ordinate (vertical, or Y-axis coordinate).
Generic vector of arbitrary length.
Vector polynomial interpolation/approximation in two dimensions.
const surface & SurfaceX() const
PointSurfacePolynomial(PointSurfacePolynomial &&)=default
PointSurfacePolynomial()=default
PointSurfacePolynomial(const PointSurfacePolynomial &)=default
void Initialize(const point_list &P1, const point_list &P2, int degree=3)
PointSurfacePolynomial(const surface &Sx, const surface &Sy)
const surface & SurfaceY() const
PointSurfacePolynomial(const point_list &P1, const point_list &P2, int degree=3)
Two-dimensional interpolating/approximating surface polynomial.
void Initialize(const T *x, const T *y, const T *z, int n)
typename vector_type::scalar scalar
void SetDegree(int degree)
virtual ~SurfacePolynomial()
SurfacePolynomial(const SurfacePolynomial &)=default
SurfacePolynomial(SurfacePolynomial &&)=default
SurfacePolynomial()=default
Complex< T > Sqrt(const Complex< T > &c) noexcept
T PowI(T x, int n) noexcept
constexpr const T & Max(const T &a, const T &b) noexcept