G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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>
21 #include <gsCore/gsLinearAlgebra.h>
22 
23 namespace gismo
24 {
31 template<class T>
33 {
34 public:
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 
81  gsMatrix<T> returnPoints() const {return m_points;}
82 
83 protected:
84 
94  bool m_closed;
95 
96 
97 }; // class gsCurveFitting
98 
99 template<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 
168 template<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 
241 template<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 
254 template<class T>
255 std::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
index_t size() const
size
Definition: gsBSplineBasis.h:165
bool m_closed
closed or not closed curve
Definition: gsCurveFitting.h:94
~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
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of Geometry abstract interface.
#define index_t
Definition: gsConfig.h:32
gsKnotVector< T > m_knots
the knot vector of the desired B-spline curve
Definition: gsCurveFitting.h:92
void computeApproxError(T &error)
computes the approximation error of the fitted curve to the original point cloud
Definition: gsCurveFitting.h:242
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
gsBSpline< T > m_curve
pointer to a B-spline curve
Definition: gsCurveFitting.h:86
gsCurveFitting()
default constructor
Definition: gsCurveFitting.h:36
gsMatrix< T > m_param_values
the parameter values of the point cloud
Definition: gsCurveFitting.h:88
gsCurveFitting(gsMatrix< T > const &param_values, gsMatrix< T > const &points, gsKnotVector< T > const &knots, const bool &closed=false)
constructor
Definition: gsCurveFitting.h:42
Class for performing a least squares fit to get a open/closed B-Spline curve for some given data...
Definition: gsCurveFitting.h:32
void compute()
computes the least squares fit for a (closed) B-spline curve
Definition: gsCurveFitting.h:100
gsMatrix< T > returnPoints() const
returns the points
Definition: gsCurveFitting.h:81
Represents a B-spline curve/function with one parameter.
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
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
Class for representing a knot vector.
Definition: gsKnotVector.h:79
This is the main header file that collects wrappers of Eigen for linear algebra.
gsMatrix< T > returnParamValues() const
returns the parameter values
Definition: gsCurveFitting.h:78
gsKnotVector< T > returnKnotVector() const
returns the knot vector
Definition: gsCurveFitting.h:75
const gsBSpline< T > & curve() const
gives back the computed B-spline curve
Definition: gsCurveFitting.h:72