G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsCurveFitting.h
Go to the documentation of this file.
1
14#pragma once
15
16#include <iostream>
17#include <stdexcept>
18
19#include <gsCore/gsGeometry.h>
20#include <gsNurbs/gsBSpline.h>
22
23namespace gismo
24{
31template<class T>
33{
34public:
37 //m_curve = NULL;
38 m_closed=false;
39 };
40
42 gsCurveFitting(gsMatrix<T> const & param_values, gsMatrix<T> const & points, gsKnotVector<T> const & knots, const bool & closed = false )
43 {
44 //m_curve = NULL;
45 m_param_values=param_values;
46 m_points=points;
47 m_knots=knots;
48 m_closed=closed;
49 };
50
53 //delete m_curve; // deleting the B-spline curve
54 };
55
56
58 void compute();
59
60 // computes the least squares fit for a periodic B-spline curve (experimental)
61 void compute_periodic();
62
64 void computeApproxError(T & error);
65
67 void setClosedCurve(bool closed){
68 m_closed=closed;
69 };
70
72 const gsBSpline<T>& curve() const { return m_curve; }
73
76
79
82
83protected:
84
95
96
97}; // class gsCurveFitting
98
99template<class T>
101{
102 //degree of knot vector i.e. degree of wanted B-spline curve
103 int m_degree=m_knots.degree();
104 // number of points
105 int num_points=m_points.rows();
106 // dimension of points will be also later dimension of coefficients
107 int m_dimension=m_points.cols();
108 // basis function definition
109 gsBSplineBasis<T> *curveBasis = new gsBSplineBasis<T>(m_knots);
110
111 //number of basis functions
112 int num_basis=curveBasis->size();
113
114
115 //for computing the value of the basis function
116 gsMatrix<T> values;
117 gsMatrix<index_t> actives;
118
119 //computing the values of the basis functions at some position
120 curveBasis->eval_into(m_param_values.transpose(),values);
121 // which functions have been computed i.e. which are active
122 curveBasis->active_into(m_param_values.transpose(),actives);
123
124 //how many rows and columns has the A matrix and how many rows has the b vector
125 int num_rows=num_basis;
126 if(m_closed==true){
127 num_rows=num_rows-m_degree;
128 }
129
130 //left side matrix
131 gsMatrix<T> m_A(num_rows,num_rows);
132 m_A.setZero(); // ensure that all entries are zero in the beginning
133 //right side vector (more dimensional!)
134 gsMatrix<T> m_B(num_rows,m_dimension);
135 m_B.setZero(); // enusure that all entris are zero in the beginning
136
137
138 // building the matrix A and the vector b of the system of linear equations A*x==b(uses automatically the information of closed or not)
139 for(index_t k=0;k<num_points;k++){
140 for(index_t i=0;i<actives.rows();i++){
141 m_B.row(actives(i,k)%num_rows) += values(i,k)*m_points.row(k);
142 for(index_t j=0;j<actives.rows();j++){
143 m_A(actives(i,k)%num_rows,actives(j,k)%num_rows) += values(i,k)*values(j,k);
144 }
145 }
146 }
147
148 //Solving the system of linear equations A*x=b (works directly for a right side which has a dimension with higher than 1)
149 gsMatrix<T> x (m_B.rows(), m_B.cols());
150 x=m_A.fullPivHouseholderQr().solve( m_B);
151
152 // making the coeffiecients ready if it was a closed or not closed curve
153 gsMatrix<T> coefs=x;
154 if(m_closed==true){
155 coefs.conservativeResize(num_rows+m_degree,m_dimension);
156 for(index_t i=0;i<m_degree;i++){
157 for(index_t j=0;j<m_dimension;j++){
158 coefs(num_rows+i,j)=coefs(i,j);
159 }
160 }
161
162 }
163 // finally generate the B-spline curve
164 m_curve = gsBSpline<T >(*curveBasis, give(coefs));
165 delete curveBasis;
166}
167
168template<class T>
170{
171 //degree of knot vector i.e. degree of wanted B-spline curve
172 int m_degree=m_knots.degree();
173 // number of points
174 int num_points=m_points.rows();
175 // dimension of points will be also later dimension of coefficients
176 int m_dimension=m_points.cols();
177 // basis function definition
178 gsBSplineBasis<T> curveBasis(m_knots, m_closed);
179
180 //number of basis functions
181 int num_basis=curveBasis.size();
182
183
184 //for computing the value of the basis function
185 gsMatrix<T> values;
186 gsMatrix<index_t> actives;
187
188 //computing the values of the basis functions at some position
189 curveBasis.eval_into(m_param_values.transpose(),values);
190 // which functions have been computed i.e. which are active
191 curveBasis.active_into(m_param_values.transpose(),actives);
192
193 //how many rows and columns has the A matrix and how many rows has the b vector
194 int num_rows=num_basis;
195
196 // No longer necessary:
197 //if(m_closed==true){
198 // num_rows=num_rows-m_degree;
199 //}
200
201 //left side matrix
202 gsMatrix<T> m_A(num_rows,num_rows);
203 m_A.setZero(); // ensure that all entries are zero in the beginning
204 //right side vector (more dimensional!)
205 gsMatrix<T> m_B(num_rows,m_dimension);
206 m_B.setZero(); // enusure that all entris are zero in the beginning
207
208
209 // building the matrix A and the vector b of the system of linear equations A*x==b(uses automatically the information of closed or not)
210 for(index_t k=0;k<num_points;k++){
211 for(index_t i=0;i<actives.rows();i++){
212 m_B.row(actives(i,k)) += values(i,k)*m_points.row(k);
213 for(index_t j=0;j<actives.rows();j++){
214 m_A(actives(i,k),actives(j,k)) += values(i,k)*values(j,k);
215 }
216 }
217 }
218
219 //Solving the system of linear equations A*x=b (works directly for a right side which has a dimension with higher than 1)
220 gsMatrix<T> x (m_B.rows(), m_B.cols());
221 x=m_A.fullPivHouseholderQr().solve( m_B);
222
223 // making the coeffiecients ready if it was a closed or not closed curve
224 gsMatrix<T> coefs=x;
225 if(m_closed==true){
226 coefs.conservativeResize(num_rows+m_degree,m_dimension);
227 for(index_t i=0;i<m_degree;i++){
228 for(index_t j=0;j<m_dimension;j++){
229 coefs(num_rows+i,j)=coefs(i,j);
230 }
231 }
232
233 }
234 curveBasis.setPeriodic(false);
235 //coefs = curveBasis->perCoefs(coefs);
236 // finally generate the B-spline curve
237 m_curve= gsBSpline<T>(curveBasis, give(coefs));
238 m_curve.setPeriodic(m_closed);
239}
240
241template<class T>
243{
244 gsMatrix<T> results;
245 // the points of the curve for the corresponding parameter values
246 m_curve.eval_into(m_param_values.transpose(),results);
247 results.transposeInPlace();
248
249 // computing the approximation error = sum_i ||x(u_i)-p_i||^2
250 error = (m_points - results).squaredNorm();
251}
252
253
254template<class T>
255std::ostream & operator <<( std::ostream &os, gsCurveFitting<T> const & cf)
256{
257 os <<"with "<< (cf.returnPoints()).rows() << " points of dimension " << (cf.returnPoints()).cols() <<
258 ". The desired B-spline curve should have degree "<< (cf.returnKnotVector()).degree() <<" with the following knot vector: " << cf.returnKnotVector() << "\n"; // cf.points
259 return os;
260}
261
262} // namespace gismo
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A B-spline function of one argument, with arbitrary target dimension.
Definition gsBSpline.h:51
Class for performing a least squares fit to get a open/closed B-Spline curve for some given data.
Definition gsCurveFitting.h:33
gsMatrix< T > m_param_values
the parameter values of the point cloud
Definition gsCurveFitting.h:88
gsKnotVector< T > m_knots
the knot vector of the desired B-spline curve
Definition gsCurveFitting.h:92
gsMatrix< T > returnParamValues() const
returns the parameter values
Definition gsCurveFitting.h:78
gsBSpline< T > m_curve
pointer to a B-spline curve
Definition gsCurveFitting.h:86
bool m_closed
closed or not closed curve
Definition gsCurveFitting.h:94
void compute()
computes the least squares fit for a (closed) B-spline curve
Definition gsCurveFitting.h:100
gsKnotVector< T > returnKnotVector() const
returns the knot vector
Definition gsCurveFitting.h:75
void computeApproxError(T &error)
computes the approximation error of the fitted curve to the original point cloud
Definition gsCurveFitting.h:242
gsCurveFitting(gsMatrix< T > const &param_values, gsMatrix< T > const &points, gsKnotVector< T > const &knots, const bool &closed=false)
constructor
Definition gsCurveFitting.h:42
gsMatrix< T > returnPoints() const
returns the points
Definition gsCurveFitting.h:81
~gsCurveFitting()
Destructor.
Definition gsCurveFitting.h:52
void setClosedCurve(bool closed)
set m_closed to true/or false since we want to have a closed/open curve
Definition gsCurveFitting.h:67
gsMatrix< T > m_points
the points of the point cloud
Definition gsCurveFitting.h:90
gsCurveFitting()
default constructor
Definition gsCurveFitting.h:36
const gsBSpline< T > & curve() const
gives back the computed B-spline curve
Definition gsCurveFitting.h:72
Class for representing a knot vector.
Definition gsKnotVector.h:80
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates nonzero basis functions at point u into result.
Definition gsBSplineBasis.hpp:260
index_t size() const
Returns the number of elements in the basis.
Definition gsBSplineBasis.h:165
void active_into(const gsMatrix< T > &u, gsMatrix< index_t > &result) const
Returns the indices of active basis functions at points u, as a list of indices, in result....
Definition gsBSplineBasis.hpp:127
Represents a B-spline curve/function with one parameter.
#define index_t
Definition gsConfig.h:32
Provides declaration of Geometry abstract interface.
This is the main header file that collects wrappers of Eigen for linear algebra.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266