mbsim  4.0.0
MBSim Kernel
nurbs_curve.h
1/* Copyright (C) 2004-2014 MBSim Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 *
17 * Contact: martin.o.foerg@googlemail.com
18 */
19
20#ifndef NURBS_CURVE_FMATVEC_H_
21#define NURBS_CURVE_FMATVEC_H_
22
23#include <mbsim/numerics/nurbs/nurbs_defs.h>
24
25namespace fmatvec {
26 typedef Matrix<General, Fixed<4>, Var, double> Mat4xV;
27
28 typedef Matrix<General, Var, Fixed<4>, double> MatVx4;
29}
30
31namespace MBSim {
32
38 class NurbsCurve {
39 public:
40 enum Method {
41 equallySpaced = 0,
42 chordLength,
43 };
44
48 NurbsCurve() = default;
49// NurbsCurve(Matrix<T> inverse) {
50// Inverse = inverse;
51// Inverse_setted = 1;
52// } //changed
53// NurbsCurve(const NurbsCurve<T, N>& nurb);
54// NurbsCurve(const Vector<fmatvec::HPoint<3> >& P1, const std::vector<double> &U1, int deg = 3);
55// NurbsCurve(const Vector<fmatvec::Point<3> >& P1, const std::vector<double> &W, const std::vector<double> &U1, int deg = 3);
56 virtual ~NurbsCurve() = default;
57
58 // Reference to internal data
60 int degree() const { return deg; }
62 const fmatvec::MatVx4 & ctrlPnts() const { return P; }
64 const fmatvec::Vec4 ctrlPnts(int i) const { return trans(P.row(i)); }
66 const fmatvec::VecV& knot() const { return U; }
68 double knot(int i) const { return U(i); }
70 const fmatvec::VecV getuVec() const { return u; }
71
72 void setKnot(const fmatvec::VecV& U_) { U = U_; }
73 void setCtrlPnts(const fmatvec::MatVx4& P_) { P = P_; }
74 void setDegree(int deg_) { deg = deg_; }
75 void setu(const fmatvec::VecV& u_) { u = u_; }
76
77 void resize(int n, int Deg);
78
79 // basic functions
80
81// virtual void reset(const Vector<fmatvec::HPoint<3> >& P1, const std::vector<double> &U1, int deg);
82// virtual NurbsCurve& operator=(const NurbsCurve<T, N>&);
83//
84// // Evaluattion functions
85 virtual fmatvec::HPoint<3> operator()(double u) const;
88 {
89 return operator()(u);
90 }
91 fmatvec::HPoint<3> hpointAt(double u, int span) const;
92 fmatvec::Point<3> pointAt(double u) const;
93// //! a function interface to operator()
94// friend fmatvec::HPoint<3> C(double u, const NurbsCurve<T, N>& nurb) {
95// return nurb(u);
96// }
97// //! returns the curvePoint in 3D
98// friend fmatvec::Point<3> Cp(double u, const NurbsCurve<T, N>& nurb) {
99// return project(nurb(u));
100// }
101
102 // derivative functions
103 void deriveAtH(double u, int d, fmatvec::MatVx4 & ders) const;
104// void deriveAt(double u, int, Vector<fmatvec::Point<3> >&) const;
105// void deriveAtH(double u, int, int, Vector<fmatvec::HPoint<3> >&) const;
106// void deriveAt(double u, int, int, Vector<fmatvec::Point<3> >&) const;
107 fmatvec::Point<3> derive3D(double u, int d) const;
108 fmatvec::HPoint<3> derive(double u, int d) const;
109 fmatvec::Point<3> normal(double u, const fmatvec::Point<3> & v) const;
110
111 fmatvec::HPoint<3> firstD(double u) const;
112 fmatvec::HPoint<3> firstD(double u, int span) const;
113 fmatvec::Point<3> firstDn(double u) const;
114 fmatvec::Point<3> firstDn(double u, int span) const;
115
116// // Basis functions
117// T basisFun(T u, int i, int p = -1) const;
118
119// void dersBasisFuns(int n, T u, int span, Matrix<T>& M) const;
120//
121// // Knot functions
122// T minKnot() const //! the minimal value for the knot vector
123// {
124// return U[0];
125// }
126// //! the maximal value for the knot vector
127// T maxKnot() const
128// {
129// return U[U.n() - 1];
130// }
131// void findMultSpan(T u, int& r, int& s) const;
132// int findMult(int r) const;
133// int findKnot(T u) const;
134// T getRemovalBnd(int r, int s) const;
135//
136// void removeKnot(int r, int s, int num);
137// void removeKnotsBound(const std::vector<double>& ub, std::vector<double>& ek, T E);
138// int knotInsertion(T u, int r, NurbsCurve<T, N>& nc);
139// void refineKnotVector(const std::vector<double>& X);
140// void refineKnotVectorClosed(const std::vector<double>& X);
141// void mergeKnotVector(const std::vector<double> &Um);
142//
143// void clamp();
144// void unclamp();
145//
146// // Curve fitting functions
147// int leastSquares(const Vector<fmatvec::Point<3> >& Q, int degC, int n);
148// int leastSquares(const Vector<fmatvec::Point<3> >& Q, int degC, int n, const std::vector<double>& ub);
149// int leastSquaresH(const Vector<fmatvec::HPoint<3> >& Q, int degC, int n, const std::vector<double>& ub);
150// int leastSquares(const Vector<fmatvec::Point<3> >& Q, int degC, int n, const std::vector<double>& ub, const std::vector<double>& knot);
151// int leastSquaresH(const Vector<fmatvec::HPoint<3> >& Q, int degC, int n, const std::vector<double>& ub, const std::vector<double>& knot);
152//
153// int leastSquaresClosed(const Vector<fmatvec::Point<3> >& Q, int degC, int n);
154// int leastSquaresClosed(const Vector<fmatvec::Point<3> >& Q, int degC, int n, const std::vector<double>& ub);
155// int leastSquaresClosedH(const Vector<fmatvec::HPoint<3> >& Q, int degC, int n, const std::vector<double>& ub);
156// int leastSquaresClosed(const Vector<fmatvec::Point<3> >& Q, int degC, int n, const std::vector<double>& ub, const std::vector<double>& knot);
157// int leastSquaresClosedH(const Vector<fmatvec::HPoint<3> >& Q, int degC, int n, const std::vector<double>& ub, const std::vector<double>& knot);
158//
159// void globalApproxErrBnd(Vector<fmatvec::Point<3> >& Q, int deg, T E);
160// void globalApproxErrBnd(Vector<fmatvec::Point<3> >& Q, std::vector<double>& ub, int deg, T E);
161// void globalApproxErrBnd2(Vector<fmatvec::Point<3> >& Q, int degC, T E);
162// void globalApproxErrBnd3(Vector<fmatvec::Point<3> >& Q, int degC, T E);
163// void globalApproxErrBnd3(Vector<fmatvec::Point<3> >& Q, const std::vector<double> &ub, int degC, T E);
164//
165// void globalInterp(const Vector<fmatvec::Point<3> >& Q, int d);
169 void globalInterp(const std::vector<fmatvec::Point<3>>& Q, const std::vector<double>& uk, int d, bool updateLater = false);
170 void globalInterp(const std::vector<fmatvec::Point<3>>& Q, double uMin, double uMax, int d, bool updateLater = false);
171 void globalInterp(const fmatvec::MatVx3& Q, double uMin, double uMax, int d, bool updateLater = false);
172
173 void globalInterpH(const fmatvec::MatVx4& Qw, int d, Method method=chordLength);
174 void globalInterpH(const fmatvec::MatVx4& Qw, const fmatvec::VecV& ub, const fmatvec::VecV& Uc, int d, bool updateLater = false);
178 void globalInterpClosed(const fmatvec::MatVx3 & Q, double uMin, double uMax, int d, bool updateLater = false);
179
183 void update(const fmatvec::MatVx3& Q);
184 void update(const fmatvec::MatVx4& Qw);
185
186 void globalInterpClosedH(const fmatvec::MatVx4& Qw, int d, Method method=chordLength);
187 void globalInterpClosedH(const fmatvec::MatVx4& Qw, const fmatvec::VecV& ub, const fmatvec::VecV& Uc, int d, bool updateLater = false);
188//
189// void globalInterpD(const Vector<fmatvec::Point<3> >& Q, const Vector<fmatvec::Point<3> >& D, int d, int unitD, T a = 1.0);
190//
191// Matrix<T> computeInverse(const std::vector<double> &v, const std::vector<double> &V, const int p);
192// Matrix<T> computeInverseClosed(const std::vector<double> &v, const std::vector<double> &V, const int p);
193//
194// void projectTo(const fmatvec::Point<3> & p, T guess, T& u, fmatvec::Point<3> & r, T e1 = 0.001, T e2 = 0.001, int maxTry = 100) const;
195//
196// T length(T eps = 0.001, int n = 100) const;
197// T lengthIn(T us, T ue, T eps = 0.001, int n = 100) const;
198// T lengthF(T) const;
199// T lengthF(T, int) const;
200//
201// // Generate type of curve
202// void makeCircle(const fmatvec::Point<3> & O, const fmatvec::Point<3> & X, const fmatvec::Point<3> & Y, T r, double as, double ae);
203// void makeCircle(const fmatvec::Point<3> & O, T r, double as, double ae);
204// void makeCircle(const fmatvec::Point<3> & O, T r);
205// void makeLine(const fmatvec::Point<3> & P0, const fmatvec::Point<3> & P1, int d);
206// virtual void degreeElevate(int t);
207//
208// #ifndef HAVE_ISO_FRIEND_DECL
209// friend void generateCompatibleCurves(NurbsCurveArray<T, N> &ca);
210// #else
211// friend void generateCompatibleCurves <>(NurbsCurveArray<T,N> &ca);
212// #endif
213//
214// void decompose(NurbsCurveArray<T, N>& c) const;
215// void decomposeClosed(NurbsCurveArray<T, N>& c) const;
216//
217// int splitAt(T u, NurbsCurve<T, N>& cl, NurbsCurve<T, N>& cu) const;
218// int mergeOf(const NurbsCurve<T, N>& cl, const NurbsCurve<T, N> &cu);
219//
220// // Modifies the NURBS curve
221// void transform(const MatrixRT<T>& A);
222 void modCP(int i, const fmatvec::HPoint<3> & a) {
223 P.set(i, a.T());
224 } // To manipulate the value of the control point $P[i]$
225// void modCPby(int i, const fmatvec::HPoint<3> & a) {
226// P[i] += a;
227// } // To manipulate the value of the control point $P[i]$
228// virtual void modKnot(const std::vector<double>& knotU) {
229// if (knotU.n() - deg_ - 1 == P.n())
230// U = knotU;
231// } // to change the values of the knot vector only if the size is compatible with P.n
232
233// int movePoint(T u, const fmatvec::Point<3> & delta);
234// int movePoint(T u, const BasicArray<fmatvec::Point<3> >& delta);
235// int movePoint(const BasicArray<T>& ur, const BasicArray<fmatvec::Point<3> >& D);
236// int movePoint(const BasicArray<T>& ur, const BasicArray<fmatvec::Point<3> >& D, const BasicArray_INT& Dr, const BasicArray_INT& Dk);
237// int movePoint(const BasicArray<T>& ur, const BasicArray<fmatvec::Point<3> >& D, const BasicArray_INT& Dr, const BasicArray_INT& Dk, const BasicArray_INT& fixCP);
238//
239// void setTangent(T u, const fmatvec::Point<3> & T0);
240// void setTangentAtEnd(const fmatvec::Point<3> & T0, const fmatvec::Point<3> & T1);
241//
242// // I/O functions
243// int read(const char*);
244// int write(const char*) const;
245// virtual int read(ifstream &fin);
246// int write(ofstream &fout) const;
247// int writePS(const char*, int cp = 0, T magFact = T(-1), T dash = T(5), bool bOpen = true) const;
248// int writePSp(const char*, const Vector<fmatvec::Point<3> >&, const Vector<fmatvec::Point<3> >&, int cp = 0, T magFact = 0.0, T dash = 5.0, bool bOpen = true) const;
249//
250// int writeVRML(ostream &fout, T radius, int K, const Color& color, int Nu, int Nv, T u_s, T u_e) const;
251// int writeVRML(const char* filename, T radius, int K, const Color& color, int Nu, int Nv, T u_s, T u_e) const;
252// int writeVRML(const char* filename, T radius = 1, int K = 5, const Color& color = whiteColor, int Nu = 20, int Nv = 20) const {
253// return writeVRML(filename, radius, K, color, Nu, Nv, U[0], U[U.n() - 1]);
254// } // writes the curve to a VRML file
255// int writeVRML(ostream& fout, T radius = 1, int K = 5, const Color& color = whiteColor, int Nu = 20, int Nv = 20) const {
256// return writeVRML(fout, radius, K, color, Nu, Nv, U[0], U[U.n() - 1]);
257// } // writes the curve to a VRML file
258//
259// int writeVRML97(const char* filename, T radius, int K, const Color& color, int Nu, int Nv, T u_s, T u_e) const;
260// int writeVRML97(ostream &fout, T radius, int K, const Color& color, int Nu, int Nv, T u_s, T u_e) const;
261// int writeVRML97(const char* filename, T radius = 1, int K = 5, const Color& color = whiteColor, int Nu = 20, int Nv = 20) const {
262// return writeVRML97(filename, radius, K, color, Nu, Nv, U[0], U[U.n() - 1]);
263// } // writes the curve to a VRML file
264// int writeVRML97(ostream& fout, T radius = 1, int K = 5, const Color& color = whiteColor, int Nu = 20, int Nv = 20) const {
265// return writeVRML97(fout, radius, K, color, Nu, Nv, U[0], U[U.n() - 1]);
266// } // writes the curve to a VRML file
267//
268// int writeDisplayLINE(const char* filename, int iNu, const Color& color = blueColor, T fA = 1) const;
269// int writeDisplayLINE(const char* filename, const Color& color, int iNu, T u_s, T u_e) const;
270// void drawImg(Image_UBYTE& Img, unsigned char color = 255, T step = 0.01);
271// void drawImg(Image_Color& Img, const Color& color, T step = 0.01);
272// void drawAaImg(Image_Color& Img, const Color& color, int precision = 3, int alpha = 1);
273// void drawAaImg(Image_Color& Img, const Color& color, const NurbsCurve<T, 3>& profile, int precision = 3, int alpha = 1);
274// NurbsSurface<T, 3> drawAaImg(Image_Color& Img, const Color& color, const NurbsCurve<T, 3>& profile, const NurbsCurve<T, 3> &scaling, int precision = 3, int alpha = 1);
275//
276// BasicList<fmatvec::Point<3> > tesselate(T tolerance, BasicList<T> *uk) const;
277
278 int findSpan(double u) const;
279
280 protected:
281 fmatvec::MatVx4 P; // the vector of control points
282 fmatvec::Vector<fmatvec::Ref, int> Aipiv;
283 fmatvec::SquareMatrix<fmatvec::Ref, double> ALU;
284 fmatvec::VecV u; // the parameteric points
285 fmatvec::VecV U; // the knot vector
286 int deg{0}; // the degree of the NURBS curve
287
288 void knotAveraging(const std::vector<double>& uk, int deg);
289 double chordLengthParam(const fmatvec::MatVx3& Q, fmatvec::VecV& ub);
290 double chordLengthParamH(const fmatvec::MatVx4& Q, fmatvec::VecV& ub);
291 double chordLengthParamClosedH(const fmatvec::MatVx4& Q, fmatvec::VecV& ub, int d);
292 void updateUVecs(double uMin, double uMax);
293
294 void knotAveragingClosed(const std::vector<double>& uk, int deg);
295 void updateUVecsClosed(double uMin, double uMax);
296
297// Matrix<T> Inverse; //changed
298// int Inverse_setted; //changed
299 };
300
301 //TODO: put those functions into mother nurbs class (maybe) to make them "func(...) const"
302 void knotAveraging(const fmatvec::VecV& uk, int deg, fmatvec::VecV& U);
303 void knotAveragingClosed(const fmatvec::VecV& uk, int deg, fmatvec::VecV& U);
304 void updateUVecs(double uMin, double uMax, fmatvec::VecV& u, int deg, fmatvec::VecV& U);
305 void updateUVecsClosed(double uMin, double uMax, fmatvec::VecV& u, int deg, fmatvec::VecV& U);
306 void basisFuns(double u, int span, int deg, const fmatvec::VecV & U, fmatvec::VecV& funs);
307 void dersBasisFuns(int n, double u, int span, int deg, const fmatvec::VecV & U, fmatvec::Mat& ders);
308 void binomialCoef(fmatvec::MatV& Bin);
309
310}
311#endif
class that copies the nurbs++-library using the fmatvec as a basis-math-library
Definition: nurbs_curve.h:38
double knot(int i) const
the i-th knot
Definition: nurbs_curve.h:68
NurbsCurve()=default
standard constructor
void globalInterpClosed(const fmatvec::MatVx3 &Q, double uMin, double uMax, int d, bool updateLater=false)
closed interpolation of the given (not yet wrapped) points at the given knot vector "ub" in a degree ...
Definition: nurbs_curve.cc:215
void update(const fmatvec::MatVx3 &Q)
update the control points with the same matrix as before
void globalInterp(const std::vector< fmatvec::Point< 3 > > &Q, const std::vector< double > &uk, int d, bool updateLater=false)
do global interpolation for given interpolation-points list and knots with the given degree
Definition: nurbs_curve.cc:105
const fmatvec::Vec4 ctrlPnts(int i) const
a reference to one of the control points
Definition: nurbs_curve.h:64
int degree() const
a reference to the degree of the curve
Definition: nurbs_curve.h:60
const fmatvec::VecV getuVec() const
a reference to the parametric points
Definition: nurbs_curve.h:70
const fmatvec::VecV & knot() const
a reference to the vector of knots
Definition: nurbs_curve.h:66
fmatvec::HPoint< 3 > hpointAt(double u) const
calls operator()
Definition: nurbs_curve.h:87
const fmatvec::MatVx4 & ctrlPnts() const
a reference to the vector of control points
Definition: nurbs_curve.h:62
wrapper class for nurbs type HPoint
Definition: nurbs_defs.h:42
wrapper class for nurbs type Point
Definition: nurbs_defs.h:13
namespace MBSim
Definition: bilateral_constraint.cc:30
void binomialCoef(MatV &Bin)
Setup a matrix containing binomial coefficients.
Definition: nurbs_curve.cc:833
void knotAveragingClosed(const VecV &uk, int deg, VecV &U)
generates a knot vector using the averaging technique for interpolation with closed curve.
Definition: nurbs_curve.cc:631