You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.2 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkSpline.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkSpline
* @brief spline abstract class for interpolating splines
*
* vtkSpline interpolates a set of data points (i.e., interpolation means
* that the spline passes through the points). vtkSpline is an abstract
* class: its subclasses vtkCardinalSpline and vtkKochanekSpline do the
* interpolation. Note that this spline maps the 1D parametric coordinate
* t into a single value x. Thus if you want to use the spline to
* interpolate points (i.e. x[3]), you have to create three splines for
* each of the x-y-z coordinates. Fortunately, the vtkParametricSpline
* class does this for you.
*
* Typically a spline is used by adding a sequence of parametric coordinate /
* data (t,x) values followed by use of an evaluation function (e.g.,
* vtkCardinalSpline::Evaluate()). Since these splines are 1D, a point in
* this context is an independent / dependent variable pair.
*
* Splines can also be set up to be closed or open. Closed splines continue
* from the last point to the first point with continuous function and
* derivative values. (You don't need to duplicate the first point to close
* the spline, just set ClosedOn.)
*
* This implementation of splines does not use a normalized parametric
* coordinate. If the spline is open, then the parameter space is (tMin <= t
* <= tMax) where tMin and tMax are the minimum and maximum parametric values
* seen when performing AddPoint(). If the spline is closed, then the
* parameter space is (tMin <= t <= (tMax+1)) where tMin and tMax are the
* minimum and maximum parametric values seen when performing AddPoint().
* Note, however, that this behavior can be changed by explicitly setting
* the ParametricRange(tMin,tMax). If set, the parameter space remains
* (tMin <= t <= tMax), except that additions of data with parametric
* values outside this range are clamped within this range.
*
* @sa
* vtkCardinalSpline vtkKochanekSpline vtkParametricSpline
* vtkParametricFunctionSource
*/
#ifndef vtkSpline_h
#define vtkSpline_h
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
class vtkPiecewiseFunction;
class VTKCOMMONDATAMODEL_EXPORT vtkSpline : public vtkObject
{
public:
vtkTypeMacro(vtkSpline, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* Set/Get the parametric range. If not set, the range is determined
* implicitly by keeping track of the (min,max) parameter values for
* t. If set, the AddPoint() method will clamp the t value to lie
* within the specified range.
*/
void SetParametricRange(double tMin, double tMax);
void SetParametricRange(double tRange[2]) { this->SetParametricRange(tRange[0], tRange[1]); }
void GetParametricRange(double tRange[2]) const;
//@}
//@{
/**
* Set/Get ClampValue. If On, results of the interpolation will be
* clamped to the min/max of the input data.
*/
vtkSetMacro(ClampValue, vtkTypeBool);
vtkGetMacro(ClampValue, vtkTypeBool);
vtkBooleanMacro(ClampValue, vtkTypeBool);
//@}
/**
* Compute the coefficients for the spline.
*/
virtual void Compute() = 0;
/**
* Interpolate the value of the spline at parametric location of t.
*/
virtual double Evaluate(double t) = 0;
/**
* Return the number of points inserted thus far.
*/
int GetNumberOfPoints();
/**
* Add a pair of points to be fit with the spline.
*/
void AddPoint(double t, double x);
/**
* Remove a point from the data to be fit with the spline.
*/
void RemovePoint(double t);
/**
* Remove all points from the data.
*/
void RemoveAllPoints();
//@{
/**
* Control whether the spline is open or closed. A closed spline forms
* a continuous loop: the first and last points are the same, and
* derivatives are continuous.
*/
vtkSetMacro(Closed, vtkTypeBool);
vtkGetMacro(Closed, vtkTypeBool);
vtkBooleanMacro(Closed, vtkTypeBool);
//@}
//@{
/**
* Set the type of constraint of the left(right) end points. Four
* constraints are available:
* 0: the first derivative at left(right) most point is determined
* from the line defined from the first(last) two points.
* 1: the first derivative at left(right) most point is set to
* Left(Right)Value.
* 2: the second derivative at left(right) most point is set to
* Left(Right)Value.
* 3: the second derivative at left(right)most points is Left(Right)Value
* times second derivative at first interior point.
*/
vtkSetClampMacro(LeftConstraint, int, 0, 3);
vtkGetMacro(LeftConstraint, int);
vtkSetClampMacro(RightConstraint, int, 0, 3);
vtkGetMacro(RightConstraint, int);
//@}
//@{
/**
* The values of the derivative on the left and right sides. The value
* is used only if the left(right) constraint is type 1-3.
*/
vtkSetMacro(LeftValue, double);
vtkGetMacro(LeftValue, double);
vtkSetMacro(RightValue, double);
vtkGetMacro(RightValue, double);
//@}
/**
* Return the MTime also considering the Piecewise function.
*/
vtkMTimeType GetMTime() override;
/**
* Deep copy of spline data.
*/
virtual void DeepCopy(vtkSpline* s);
protected:
vtkSpline();
~vtkSpline() override;
vtkMTimeType ComputeTime;
vtkTypeBool ClampValue;
double* Intervals;
double* Coefficients;
int LeftConstraint;
double LeftValue;
int RightConstraint;
double RightValue;
vtkPiecewiseFunction* PiecewiseFunction;
vtkTypeBool Closed;
// Explicitly specify the parametric range.
double ParametricRange[2];
// Helper methods
double ComputeLeftDerivative();
double ComputeRightDerivative();
int FindIndex(int size, double t);
private:
vtkSpline(const vtkSpline&) = delete;
void operator=(const vtkSpline&) = delete;
};
#endif