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
25 namespace fmatvec {
26 typedef Matrix<General, Fixed<4>, Var, double> Mat4xV;
27
28 typedef Matrix<General, Var, Fixed<4>, double> MatVx4;
29 }
30
31 namespace 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;
87 fmatvec::HPoint<3> hpointAt(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
MBSim::NurbsCurve::ctrlPnts
const fmatvec::MatVx4 & ctrlPnts() const
a reference to the vector of control points
Definition: nurbs_curve.h:62
MBSim::knotAveragingClosed
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
MBSim::NurbsCurve::update
void update(const fmatvec::MatVx3 &Q)
update the control points with the same matrix as before
MBSim::NurbsCurve::knot
double knot(int i) const
the i-th knot
Definition: nurbs_curve.h:68
MBSim::NurbsCurve::hpointAt
fmatvec::HPoint< 3 > hpointAt(double u) const
calls operator()
Definition: nurbs_curve.h:87
MBSim::NurbsCurve::ctrlPnts
const fmatvec::Vec4 ctrlPnts(int i) const
a reference to one of the control points
Definition: nurbs_curve.h:64
MBSim::binomialCoef
void binomialCoef(MatV &Bin)
Setup a matrix containing binomial coefficients.
Definition: nurbs_curve.cc:833
MBSim::NurbsCurve::degree
int degree() const
a reference to the degree of the curve
Definition: nurbs_curve.h:60
fmatvec::HPoint
wrapper class for nurbs type HPoint
Definition: nurbs_defs.h:42
MBSim::NurbsCurve::globalInterp
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
MBSim::NurbsCurve::NurbsCurve
NurbsCurve()=default
standard constructor
fmatvec::Point
wrapper class for nurbs type Point
Definition: nurbs_defs.h:13
MBSim::NurbsCurve::globalInterpClosed
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
MBSim::NurbsCurve
class that copies the nurbs++-library using the fmatvec as a basis-math-library
Definition: nurbs_curve.h:38
MBSim::NurbsCurve::getuVec
const fmatvec::VecV getuVec() const
a reference to the parametric points
Definition: nurbs_curve.h:70
MBSim::NurbsCurve::knot
const fmatvec::VecV & knot() const
a reference to the vector of knots
Definition: nurbs_curve.h:66
MBSim
namespace MBSim
Definition: bilateral_constraint.cc:30