-
Notifications
You must be signed in to change notification settings - Fork 19
/
vtkParametricPolynomialApproximation.h
192 lines (160 loc) · 6.73 KB
/
vtkParametricPolynomialApproximation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Thomas Vaughan, PerkLab, Queen's University.
==============================================================================*/
/**
* @class vtkParametricPolynomialApproximation
* @brief parametric function for 1D polynomials
*
* vtkParametricPolynomialApproximation is a parametric function for 1D approximating
* polynomials. vtkParametricPolynomialApproximation maps the single parameter u to a
* 3D point (x,y,z). Internally a polynomial is fit to a set of input
* points using the least squares basis.
*/
#ifndef vtkParametricPolynomialApproximation_h
#define vtkParametricPolynomialApproximation_h
class vtkPoints;
class vtkDoubleArray;
class vtkTimeStamp;
#include "vtkAddonExport.h" // For export macro
#include <vtkParametricFunction.h>
#include <vtkSmartPointer.h>
class VTK_ADDON_EXPORT vtkParametricPolynomialApproximation : public vtkParametricFunction
{
public:
vtkTypeMacro(vtkParametricPolynomialApproximation, vtkParametricFunction);
void PrintSelf(ostream& os, vtkIndent indent) override;
static vtkParametricPolynomialApproximation *New();
/**
* Return the parametric dimension of the class.
*/
int GetDimension() override { return 1; }
/**
* Evaluate the parametric function at parametric coordinate u[0] returning
* the point coordinate Pt[3].
*/
void Evaluate(double u[3], double Pt[3], double Du[9]) override;
/**
* Evaluate a scalar value at parametric coordinate u[0] and Pt[3].
* Simply returns the parameter u[0].
*/
double EvaluateScalar(double u[3], double Pt[3], double Du[9]) override;
//@{
/**
* Specify the order of polynomial (maximum exponent) that should be fit.
*/
vtkGetMacro(PolynomialOrder, int);
vtkSetMacro(PolynomialOrder, int);
//@}
//@{
/**
* Specify the list of points that the polynomial should approximate.
* Set the point parameters that should be used during fitting with SetParameters.
*/
void SetPoints(vtkPoints*);
//@}
//@{
/**
* Specify the parameters for the points. Length of list should be the same,
* and the points should be in the same order as the parameters.
*/
void SetParameters(vtkDoubleArray*);
//@}
//@{
/**
* Fitting options, see FitMethod
*/
enum {
FIT_METHOD_GLOBAL_LEAST_SQUARES = 0, // global fit
FIT_METHOD_MOVING_LEAST_SQUARES, // local fit
FIT_METHOD_LAST // valid types go above this line
};
//@}
//@{
/**
* What type of fit should be used (e.g. global/local)
*/
vtkGetMacro(FitMethod, int);
vtkSetMacro(FitMethod, int);
void SetFitMethodToGlobalLeastSquares() { this->SetFitMethod(vtkParametricPolynomialApproximation::FIT_METHOD_GLOBAL_LEAST_SQUARES); }
void SetFitMethodToMovingLeastSquares() { this->SetFitMethod(vtkParametricPolynomialApproximation::FIT_METHOD_MOVING_LEAST_SQUARES); }
//@}
//@{
/**
* Options for weighing points in moving least squares, see WeightFunction
*/
enum {
WEIGHT_FUNCTION_RECTANGULAR = 0, // All points within the sampling width (see above) are treated with equal importance
WEIGHT_FUNCTION_TRIANGULAR, // Points closer are treated as more important, falloff is linear
WEIGHT_FUNCTION_COSINE, // Points closer are treated as more important, falloff curve follows a smooth cosine
WEIGHT_FUNCTION_GAUSSIAN, // Points closer are treated as more important, falloff curve follows a smooth gaussian with 5% cutoff
WEIGHT_FUNCTION_LAST // valid types go above this line
};
//@}
//@{
/**
* Specify the order of polynomial (maximum exponent) that should be fit.
*/
vtkGetMacro(WeightFunction, int);
vtkSetMacro(WeightFunction, int);
void SetWeightFunctionToRectangular() { this->SetWeightFunction(vtkParametricPolynomialApproximation::WEIGHT_FUNCTION_RECTANGULAR); }
void SetWeightFunctionToTriangular() { this->SetWeightFunction(vtkParametricPolynomialApproximation::WEIGHT_FUNCTION_TRIANGULAR); }
void SetWeightFunctionToCosine() { this->SetWeightFunction(vtkParametricPolynomialApproximation::WEIGHT_FUNCTION_COSINE); }
void SetWeightFunctionToGaussian() { this->SetWeightFunction(vtkParametricPolynomialApproximation::WEIGHT_FUNCTION_GAUSSIAN); }
//@}
//@{
/**
* The width of sampling for moving least squares (in parameter space)
* This is total width, so the space that is sampled is
* SamplePosition - ( SampleWidth / 2 ) through to
* SamplePosition + ( SampleWidth / 2 ).
* Valid range is from 0.0 to 1.0. Default is 0.5.
*/
vtkGetMacro(SampleWidth, double);
vtkSetMacro(SampleWidth, double);
//@}
protected:
vtkParametricPolynomialApproximation();
~vtkParametricPolynomialApproximation() override;
private:
// What kind of fit (global/local)
int FitMethod;
// These apply to all types of polynomials
int PolynomialOrder;
vtkSmartPointer< vtkDoubleArray > Parameters;
vtkSmartPointer< vtkPoints > Points;
double SamplePosition; // Internally store the sample position queried by the user
// These apply only to moving least squares (for now)
vtkSmartPointer< vtkDoubleArray > Weights; // Internally compute and store weights
vtkSmartPointer< vtkDoubleArray > SortedParameters; // Internally computed, same values as Parameters but sorted
int WeightFunction;
double SampleWidth;
double SafeSampleWidth; // internally computed, ensures that moving least squares polynomials are always computed in parameters 0..1
vtkTimeStamp SafeHalfSampleWidthComputedTime;
// This is directly used to evaluate points in 3D (in a sense this is the "output")
vtkSmartPointer< vtkDoubleArray > Coefficients;
// Logic functions
void ComputeCoefficients();
bool ComputeCoefficientsNeeded();
void ComputeWeights();
void ComputeWeightsGlobalLeastSquares();
void ComputeWeightsMovingLeastSquares();
bool ComputeWeightsNeeded();
void ComputeSortedParameters();
bool ComputeSortedParametersNeeded();
void ComputeSafeSampleWidth();
bool ComputeSafeSampleWidthNeeded();
static void FitLeastSquaresPolynomials(vtkDoubleArray* parameters, vtkPoints* points,
vtkDoubleArray* weights, int polynomialOrder, vtkDoubleArray* coefficients);
vtkParametricPolynomialApproximation(const vtkParametricPolynomialApproximation&) = delete;
void operator=(const vtkParametricPolynomialApproximation&) = delete;
};
#endif