G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsNurbsCreator.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsMultiPatch.h>
17 
19 #include <gsNurbs/gsTensorNurbs.h>
20 #include <gsNurbs/gsNurbs.h>
21 #include <gsNurbs/gsBSpline.h>
22 #include <math.h>
23 
24 namespace gismo
25 {
26 
27 /*
28  @brief Class gsNurbsCreator provides some simple examples of Nurbs Geometries
29 */
30 
31 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
32 gsNurbsCreator<T>::rotate2D(gsTensorBSpline<2,T> const & geo, const T turndeg, const T Tx, const T Ty)
33 {
34  GISMO_ASSERT(geo.geoDim() >= 2,"Geometry must be 2D or higher");
35 
36  const T pi = 3.1415926535897932384626433832795;
37  T r = turndeg / 180 * pi;
38  T tx, ty;
39 
40  gsMatrix<T> newcoefs = geo.coefs();
41 
42 
43  for(index_t i =0; i < geo.coefs().rows(); i++)
44  {
45  tx = newcoefs(i,0);
46  ty = newcoefs(i,1);
47  newcoefs(i,0) = math::cos(r) * (tx-Tx) - math::sin(r) * (ty-Ty) + Tx;
48  newcoefs(i,1) = math::sin(r) * (tx-Tx) + math::cos(r) * (ty-Ty) + Ty;
49  }
50 
51  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(geo.basis().knots(0),geo.basis().knots(1), give(newcoefs) ));
52 }
53 
54 template <class T>
55 void gsNurbsCreator<T>::rotate2D(gsGeometry<T> & geo, const T turndeg, const T Tx, const T Ty)
56 {
57  const T pi = 3.1415926535897932384626433832795;
58  T r = turndeg / 180 * pi;
59 
60  T tx, ty;
61  for(index_t i =0; i < geo.coefs().rows(); i++)
62  {
63  tx = geo.coefs()(i,0);
64  ty = geo.coefs()(i,1);
65  geo.coefs()(i,0) = math::cos(r) * (tx-Tx) - math::sin(r) * (ty-Ty) + Tx;
66  geo.coefs()(i,1) = math::sin(r) * (tx-Tx) + math::cos(r) * (ty-Ty) + Ty;
67  }
68 }
69 
70 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
71 gsNurbsCreator<T>::shift2D(gsTensorBSpline<2,T> const & geo, const T dx, const T dy, const T dz)
72 {
73  GISMO_ASSERT(geo.geoDim() >= 2,"Geometry must be 2D or higher");
74  gsMatrix<T> newcoefs = geo.coefs();
75 
76  newcoefs.col(0) += gsVector<T>::Ones(newcoefs.rows())*dx;
77  newcoefs.col(1) += gsVector<T>::Ones(newcoefs.rows())*dy;
78  if (newcoefs.cols()==3)
79  newcoefs.col(2) += gsVector<T>::Ones(newcoefs.rows())*dz;
80 
81  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(geo.basis().knots(0),geo.basis().knots(1), give(newcoefs) ));
82 }
83 
84 template <class T>
85 void gsNurbsCreator<T>::shift2D(gsGeometry<T> & geo, const T dx, const T dy, const T dz)
86 {
87  geo.coefs().col(0) += gsVector<T>::Ones(geo.coefs().rows())*dx;
88  geo.coefs().col(1) += gsVector<T>::Ones(geo.coefs().rows())*dy;
89  if (geo.coefs().cols()==3)
90  geo.coefs().col(2) += gsVector<T>::Ones(geo.coefs().rows())*dz;
91 }
92 
93 template<class T>
94 void gsNurbsCreator<T>::shift2D(gsMultiPatch<T> & mp, const T dx, const T dy, const T dz)
95 {
96  for (size_t k = 0; k!=mp.nPatches(); k++)
97  shift2D(mp.patch(k),dx,dy,dz);
98 }
99 
100 template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
101 gsNurbsCreator<T>::mirror2D(gsTensorBSpline<2,T> & geo, bool axis)
102 {
103  gsMatrix<T> newcoefs = geo.coefs();
104 
105  T mid = newcoefs.col(!axis).maxCoeff() - newcoefs.col(!axis).minCoeff();
106  newcoefs.col(!axis) -= gsVector<T>::Ones(newcoefs.rows())*mid;
107  newcoefs.col(!axis) *= -1;
108 
109  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(geo.basis().knots(0),geo.basis().knots(1), give(newcoefs) ));
110 }
111 
112 template <class T>
113 void gsNurbsCreator<T>::mirror2D(gsGeometry<T> & geo, bool axis)
114 {
115  T mid = geo.coefs().col(!axis).maxCoeff() - geo.coefs().col(!axis).minCoeff();
116  geo.coefs().col(!axis) -= gsVector<T>::Ones(geo.coefs().rows())*mid;
117  geo.coefs().col(!axis) *= -1;
118 
119 }
120 
121 template <class T>
122 void gsNurbsCreator<T>::mirror2D(gsMultiPatch<T> & mp, bool axis)
123 {
124  gsMatrix<T> bbox;
125  mp.boundingBox(bbox);
126 
127  T mid = (bbox(!axis,1)+bbox(!axis,0))/2;
128  for (size_t p = 0; p!=mp.nPatches(); p++)
129  {
130  mp.patch(p).coefs().col(!axis) -= gsVector<T>::Ones(mp.patch(p).coefs().rows())*mid;
131  mp.patch(p).coefs().col(!axis) *= -1;
132  }
133 }
134 
135 template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
136 gsNurbsCreator<T>::scale2D(gsTensorBSpline<2,T> const & geo, T factor)
137 {
138  gsMatrix<T> newcoefs = geo.coefs();
139  for (index_t k = 0; k!= newcoefs.cols(); k++)
140  {
141  newcoefs.col(k) *= factor;
142  }
143  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(geo.basis().knots(0),geo.basis().knots(1), give(newcoefs) ));
144 }
145 
146 template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
147 gsNurbsCreator<T>::scale2D(gsTensorBSpline<2,T> const & geo, std::vector<T> factors)
148 {
149  gsMatrix<T> newcoefs = geo.coefs();
150  GISMO_ENSURE(factors.size()==static_cast<size_t>(newcoefs.cols()),"Number of scaling factors must be the same as the number of dimensions");
151  for (index_t k = 0; k!= newcoefs.cols(); k++)
152  {
153  newcoefs.col(k) *= factors.at(k);
154  }
155  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(geo.basis().knots(0),geo.basis().knots(1), give(newcoefs) ));
156 }
157 
158 template <class T>
159 void gsNurbsCreator<T>::scale2D(gsGeometry<T> & geo, T factor)
160 {
161  for (index_t k = 0; k!= geo.coefs().cols(); k++)
162  {
163  geo.coefs().col(k) *= factor;
164  }
165 }
166 
167 template <class T>
168 void gsNurbsCreator<T>::scale2D(gsGeometry<T> & geo, std::vector<T> factors)
169 {
170  GISMO_ENSURE(factors.size()==static_cast<size_t>(geo.coefs().cols()),"Number of scaling factors must be the same as the number of dimensions");
171  for (index_t k = 0; k!= geo.coefs().cols(); k++)
172  {
173  geo.coefs().col(k) *= factors.at(k);
174  }
175 }
176 
177 template <class T>
178 void gsNurbsCreator<T>::scale2D(gsMultiPatch<T> & mp, T factor)
179 {
180  for (size_t p = 0; p!=mp.nPatches(); p++)
181  scale2D(mp.patch(p),factor);
182 }
183 
184 template <class T>
185 void gsNurbsCreator<T>::scale2D(gsMultiPatch<T> & mp, std::vector<T> factors)
186 {
187  for (size_t p = 0; p!=mp.nPatches(); p++)
188  scale2D(mp.patch(p),factors);
189 }
190 
191 template <typename T>
192 void gsNurbsCreator<T>::makeGrid(gsMultiPatch<T> & mp, const index_t M, const index_t N)
193 {
194  gsMultiPatch<T> mp_ori(mp);
195  gsMatrix<T> bbox;
196  mp.boundingBox(bbox);
197 
198  T L = bbox(0,1)-bbox(0,0);
199  T H = bbox(1,1)-bbox(1,0);
200 
201  mp.clear();
202  for (index_t m = 0; m!=M; m++)
203  for (index_t n = 0; n!=N; n++)
204  {
205  gsMultiPatch<T> mp_tmp(mp_ori);
206  shift2D(mp_tmp,(m)*L,(n)*H);
207  for (size_t k=0; k!=mp_tmp.nPatches(); k++)
208  mp.addPatch(mp_tmp.patch(k));
209  }
210  mp.computeTopology();
211 }
212 
213 template <typename T>
214 gsMultiPatch<T> gsNurbsCreator<T>::makeGrid(std::vector<gsMultiPatch<T>> & mps, const index_t M, const index_t N)
215 {
216  gsMultiPatch<T> mp;
217 
218  std::vector<gsMultiPatch<T>> mps_ori(mps);
219  std::vector<T> Hs,Ls;
220  Hs.reserve(mps.size());
221  Ls.reserve(mps.size());
222  gsMatrix<T> bbox;
223  for (typename std::vector<gsMultiPatch<T>>::iterator it = mps.begin(); it!=mps.end(); it++)
224  {
225  it->boundingBox(bbox);
226  Ls.push_back(bbox(0,1)-bbox(0,0));
227  Hs.push_back(bbox(1,1)-bbox(1,0));
228  }
229 
230  typename std::vector<gsMultiPatch<T>>::iterator mp_it = mps.begin();
231  typename std::vector<T>::iterator L_it = Ls.begin();
232  typename std::vector<T>::iterator H_it = Hs.begin();
233  for (index_t m = 0; m!=M; m++)
234  {
235  for (index_t n = 0; n!=N; n++)
236  {
237  gsMultiPatch<T> mp_tmp(*mp_it);
238  shift2D(mp_tmp,(m)*(*L_it),(n)*(*H_it));
239  for (size_t k=0; k!=mp_tmp.nPatches(); k++)
240  mp.addPatch(mp_tmp.patch(k));
241 
242  mp_it==mps.end()-1 ? mp_it = mps.begin() : mp_it++;
243  L_it==Ls.end()-1 ? L_it = Ls.begin() : L_it++;
244  H_it==Hs.end()-1 ? H_it = Hs.begin() : H_it++;
245  }
246 
247  // if the size of mps is and if n is even, we need to add to the iterators to make sure the pattern is alternating
248  if (mps.size() % 2 == 0 && N % 2 == 0)
249  {
250  mp_it==mps.end()-1 ? mp_it = mps.begin() : mp_it++;
251  L_it==Ls.end()-1 ? L_it = Ls.begin() : L_it++;
252  H_it==Hs.end()-1 ? H_it = Hs.begin() : H_it++;
253  }
254  }
255  mp.computeTopology();
256  return mp;
257 }
258 
259 template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
260 gsNurbsCreator<T>::lift3D( gsTensorBSpline<2,T> const & geo, T z)
261 {
262  gsKnotVector<T> KV(0, 1, 0, 2);
263  const int sz = geo.basis().size();
264 
265  gsMatrix<T> newcoefs( 2*sz, geo.geoDim() ) ;
266 
267  // Copy coefficients
268  newcoefs.topRows(sz) =
269  newcoefs.bottomRows(sz) = geo.coefs();
270 
271  // Embed in 3D if needed
272  if (newcoefs.cols() == 2 )
273  {
274  newcoefs.conservativeResize( gsEigen::NoChange, 3);
275  newcoefs.col(2).setZero();
276  }
277 
278  // Lift
279  newcoefs.col(2).bottomRows(sz).array() += z;
280 
281  return TensorBSpline3Ptr(new gsTensorBSpline<3,T>(geo.basis().knots(0),
282  geo.basis().knots(1),
283  KV, give(newcoefs) ));
284 }
285 
286 
287 template<class T> typename gsNurbsCreator<T>::TensorBSpline4Ptr
288 gsNurbsCreator<T>::lift4D( gsTensorBSpline<3,T> const & geo, T z)
289 {
290  gsKnotVector<T> KV(0, 1, 0, 2);
291  const int sz = geo.basis().size();
292 
293  gsMatrix<T> newcoefs( 2*sz, geo.geoDim() ) ;
294 
295  // Copy coefficients
296  newcoefs.topRows(sz) =
297  newcoefs.bottomRows(sz) = geo.coefs();
298 
299  // Embed in 4D if needed
300  if (newcoefs.cols() == 3 )
301  {
302  newcoefs.conservativeResize( gsEigen::NoChange, 4);
303  newcoefs.col(3).setZero();
304  }
305 
306  // Lift
307  newcoefs.col(3).bottomRows(sz).array() += z;
308 
309  return TensorBSpline4Ptr(new gsTensorBSpline<4,T>(geo.basis().knots(0),
310  geo.basis().knots(1),
311  geo.basis().knots(2),
312  KV, give(newcoefs) ));
313 }
314 
315 
316 template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
317 gsNurbsCreator<T>::lift3D( gsTensorNurbs<2,T> const & geo, T z)
318 {
319  gsKnotVector<T> KV(0, 1, 0, 2);
320  const int sz = geo.basis().size();
321 
322  gsMatrix<T> newweights(2*sz, 1), newcoefs( 2*sz, geo.geoDim() ) ;
323 
324  // Copy coefficients
325  newcoefs.topRows(sz) =
326  newcoefs.bottomRows(sz) = geo.coefs();
327 
328  // Copy weights
329  newweights.topRows(sz) =
330  newweights.bottomRows(sz) = geo.basis().weights();
331 
332  // Embed in 3D if needed
333  if (newcoefs.cols() == 2 )
334  {
335  newcoefs.conservativeResize( gsEigen::NoChange, 3);
336  newcoefs.col(2).setZero();
337  }
338 
339  // Lift
340  newcoefs.col(2).bottomRows(sz).array() += z;
341 
342  return TensorNurbs3Ptr(new gsTensorNurbs<3,T>(geo.basis().knots(0),
343  geo.basis().knots(1),
344  KV, give(newcoefs), give(newweights) ));
345 }
346 
347 
348 template<class T> typename gsNurbsCreator<T>::TensorNurbs4Ptr
349 gsNurbsCreator<T>::lift4D( gsTensorNurbs<3,T> const & geo, T z)
350 {
351  gsKnotVector<T> KV(0, 1, 0, 2);
352  const int sz = geo.basis().size();
353 
354  gsMatrix<T> newweights(2*sz, 1), newcoefs(2*sz, geo.geoDim());
355 
356  // Copy coefficients
357  newcoefs.topRows(sz) =
358  newcoefs.bottomRows(sz) = geo.coefs();
359 
360  // Copy weights
361  newweights.topRows(sz) =
362  newweights.bottomRows(sz) = geo.basis().weights();
363 
364  // Embed in 4D if needed
365  if (newcoefs.cols() == 3 )
366  {
367  newcoefs.conservativeResize( gsEigen::NoChange, 4);
368  newcoefs.col(3).setZero();
369  }
370 
371  // Lift
372  newcoefs.col(3).bottomRows(sz).array() += z;
373 
374  return TensorNurbs4Ptr(new gsTensorNurbs<4,T>(geo.basis().knots(0),
375  geo.basis().knots(1),
376  geo.basis().knots(2),
377  KV, give(newcoefs), give(newweights) ));
378 }
379 
380 /* * Computes a set of control points, weights, and knots that define an order-3 circular arc centered at the origin
381  \param X Defines the X axis of the plane containing the arc
382  \param Y Defines the Y axis of the plane containing the arc
383  \param StartAngle Start angle of the arc in radians
384  \param EndAngle End angle of the arc in radians
385  \param Segments The number of NURBS segments in the resulting arc
386  \param Knots Output container for the resulting arc knot vector
387  \param Weights Output container for the resulting arc control point weights
388  \param ControlPoints Output container for the resulting arc control point positions
389 
390  template<class T> gsNurbsCreator<T> * gsNurbsCreator<T>::circularArc(const vector3& X, const vector3& Y,
391  const T StartAngle, const T EndAngle,
392  const unsinged Segments = 1)
393  {
394  gsKnotVector<T> Knots;
395  gsMatrix<T> Weights;
396  gsMatrix<T> ControlPoints;
397 
398  const T theta = (EndAngle - StartAngle) / static_cast<T>(Segments);
399  const T weight = math::cos(math::abs(theta) * 0.5);
400 
401  Knots.clear();
402  Knots.insert(Knots.end(), 3, 0);
403  for(uint_t i = 1; i != Segments; ++i)
404  Knots.insert(Knots.end(), 2, i);
405  Knots.insert(Knots.end(), 3, Segments);
406 
407  Weights.clear();
408  Weights.push_back(1.0);
409  for(uint_t i = 0; i != Segments; ++i)
410  {
411  Weights.push_back(weight);
412  Weights.push_back(1);
413  }
414 
415  ControlPoints.clear();
416  ControlPoints.push_back(k3d::to_point(std::cos(StartAngle) * X + std::sin(StartAngle) * Y));
417  for(uint_t i = 0; i != Segments; ++i)
418  {
419  const T a0 = math::mix(StartAngle, EndAngle, static_cast<T>(i) / static_cast<T>(Segments));
420  const T a2 = math::mix(StartAngle, EndAngle, static_cast<T>(i+1) / static_cast<T>(Segments));
421 
422  const point3 p0(k3d::to_point(std::cos(a0) * X + std::sin(a0) * Y));
423  const point3 p2(k3d::to_point(std::cos(a2) * X + std::sin(a2) * Y));
424 
425  const point3 t0(k3d::to_point(-std::sin(a0) * X + std::cos(a0) * Y));
426  const point3 t2(k3d::to_point(-std::sin(a2) * X + std::cos(a2) * Y));
427 
428  point3 p1;
429  intersect_lines(p0, to_vector(t0), p2, to_vector(t2), p1);
430 
431  ControlPoints.push_back(p1);
432  ControlPoints.push_back(p2);
433  }
434  }
435 */
436 
437 template<class T> typename gsNurbsCreator<T>::BSplinePtr
438 gsNurbsCreator<T>::BSplineUnitInterval(short_t deg)
439 {
440  gsKnotVector<T> KV(0,1, 0,deg+1);
441  gsMatrix<T> C(deg+1, 1);
442  for (short_t i = 0; i <= deg; ++i)
443  C(i) = static_cast<T>(i) / static_cast<T>(deg);
444  return BSplinePtr(new gsBSpline<T>(KV, give(C)));
445 }
446 
448 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
450  T const & low_y,
451  T const & upp_x,
452  T const & upp_y, T const & turndeg)
453 {
454 
455  gsKnotVector<T> KV (0,1,0,3);
456  gsMatrix<T> C(4,2);
457 
458  const T pi = 3.1415926535897932384626433832795;
459 
460  T r = turndeg / (T)(180) * pi;
461 
462  C << low_x, low_y ,
463  upp_x, low_y,
464  low_x, upp_y,
465  upp_x, upp_y;
466 
467  T tx;
468  T ty;
469  for(int i =0; i < 4; i++)
470  {
471  tx = C(i,0); ty = C(i,1);
472  C(i,0) = math::cos(r) * tx - math::sin(r) * ty;
473  C(i,1) = math::sin(r) * tx + math::cos(r) * ty;
474  }
475 
476  gsMatrix<T> D(9,2);
477  D.setZero();
478  D(0,0) = C(0,0); D(0,1) = C(0,1);
479  D(2,0) = C(1,0); D(2,1) = C(1,1);
480  D(6,0) = C(2,0); D(6,1) = C(2,1);
481  D(8,0) = C(3,0); D(8,1) = C(3,1);
482 
483  D(1,0) = (C(0,0)+C(1,0))/(T)(2); D(1,1) = (C(0,1)+C(1,1))/(T)(2);
484  D(3,0) = (C(0,0)+C(2,0))/(T)(2); D(3,1) = (C(0,1)+C(2,1))/(T)(2);
485  D(5,0) = (C(3,0)+C(1,0))/(T)(2); D(5,1) = (C(3,1)+C(1,1))/(T)(2);
486  D(7,0) = (C(2,0)+C(3,0))/(T)(2); D(7,1) = (C(2,1)+C(3,1))/(T)(2);
487  D(4,0) = (C(0,0)+C(3,0))/(T)(2); D(4,1) = (C(0,1)+C(3,1))/(T)(2);
488 
489  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(D)));
490 
491 }
492 
493 /*
494  Ltop
495  <-------------------->
496  C *--------------------* D
497  / ^ \
498  / | H \
499  A *---------------------------* B
500  <->
501  d
502  <--------------------------->
503  Lbot
504  */
505 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
506 gsNurbsCreator<T>::BSplineTrapezium( T const & Ax, T const & Ay,
507  T const & Bx, T const & By,
508  T const & Cx, T const & Cy,
509  T const & Dx, T const & Dy,
510  T const & turndeg)
511 {
512 
513  gsKnotVector<T> KV (0,1,0,2) ;
514  gsMatrix<T> C(4,2);
515 
516  const T pi = 3.1415926535897932384626433832795;
517 
518  T r = turndeg / 180. * pi;
519 
520  C << Ax, Ay,
521  Bx, By,
522  Cx, Cy,
523  Dx, Dy;
524 
525  T tx;
526  T ty;
527  for(int i =0; i < 4; i++)
528  {
529  tx = C(i,0); ty = C(i,1);
530  C(i,0) = math::cos(r) * tx - math::sin(r) * ty;
531  C(i,1) = math::sin(r) * tx + math::cos(r) * ty;
532  }
533 
534  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(C)));
535 
536 }
537 
538 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
540  T const & Ltop,
541  T const & H,
542  T const & d, T const & turndeg)
543 {
544  T Ax,Ay,Bx,By,Cx,Cy,Dx,Dy;
545  Ax = Ay = By = 0.0;
546  Bx = Lbot;
547  Cx = d;
548  Dx = d+Ltop;
549  Cy = Dy = H;
550 
551  return BSplineTrapezium(Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,turndeg);
552 }
553 
554 
555 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
556 gsNurbsCreator<T>::BSplineRectangleWithPara( T low_x, T low_y, T upp_x, T upp_y)
557 {
558  gsKnotVector<T> KVx (low_x, upp_x, 0, 2);
559  gsKnotVector<T> KVy (low_y, upp_y, 0, 2);
560 
561  gsMatrix<T> C(4,2);
562 
563  C << low_x, low_y,
564  upp_x, low_y,
565  low_x, upp_y,
566  upp_x, upp_y;
567 
568  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KVx, KVy, give(C)));
569 }
570 
571 /*
572  Ltop
573  <-------------------->
574  C *--------------------* D *
575  / ^ \
576  * | * \
577  / | H \
578  A *--------------*------------* B
579  <->
580  d
581  <--------------------------->
582  Lbot
583 
584  Where BD is an arc
585  */
586 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
587 gsNurbsCreator<T>::NurbsArcTrapezium( T const & Ax, T const & Ay,
588  T const & Bx, T const & By,
589  T const & Cx, T const & Cy,
590  T const & Dx, T const & Dy,
591  T const & turndeg)
592 {
593 
594  gsKnotVector<T> KV1 (0,1,0,2);
595  gsKnotVector<T> KV2 (0,1,0,3);
596  gsMatrix<T> C(4,2);
597 
598  const T pi = 3.1415926535897932384626433832795;
599 
600  T r = turndeg / 180 * pi;
601 
602  C << Ax, Ay,
603  Bx, By,
604  Cx, Cy,
605  Dx, Dy;
606 
607  gsDebugVar(C);
608 
609 
610  gsMatrix<T> D(6,2);
611  D.setZero();
612  D(0,0) = C(0,0); D(0,1) = C(0,1);
613  D(1,0) = C(1,0); D(1,1) = C(1,1);
614  D(4,0) = C(2,0); D(4,1) = C(2,1);
615  D(5,0) = C(3,0); D(5,1) = C(3,1);
616 
617  D(2,0) = (C(0,0)+C(2,0))/2; D(2,1) = (C(0,1)+C(2,1))/2;
618  D(3,0) = C(3,0); D(3,1) = C(0,0);
619 
620  gsDebugVar(D);
621 
622  T tx;
623  T ty;
624  for(int i =0; i < 6; i++)
625  {
626  tx = D(i,0); ty = D(i,1);
627  D(i,0) = math::cos(r) * tx - math::sin(r) * ty;
628  D(i,1) = math::sin(r) * tx + math::cos(r) * ty;
629  }
630 
631  gsMatrix<T> newweights(6, 1);
632  newweights.setOnes();
633  newweights(3,0) = 0.7071;
634 
635  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(KV1,KV2, give(D),newweights));
636 
637 }
638 
639 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
641  T const & Ltop,
642  T const & H,
643  T const & d, T const & turndeg)
644 {
645  T Ax,Ay,Bx,By,Cx,Cy,Dx,Dy;
646  Ax = Ay = By = 0.0;
647  Bx = Lbot;
648  Cx = d;
649  Dx = d+Ltop;
650  Cy = Dy = H;
651 
652  return NurbsArcTrapezium(Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,turndeg);
653 }
654 
655 
657 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
659  T const & x,
660  T const & y)
661 {
662  gsKnotVector<T> KV (0,1,0,2) ;
663  gsMatrix<T> C(4,2) ;
664 
665  C << 0 , 0 , 1 , 0
666  , 0 , 1 , 1 , 1 ;
667  // scale
668  C *= r;
669 
670  // translate
671  C.col(0).array() += x;
672  C.col(1).array() += y;
673 
674  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(C)));
675 }
676 
690 template<class T> gsMultiPatch<T>
692  T const & r,
693  T const & lx,
694  T const & ly)
695 {
696  gsMultiPatch<T> mp;
697 
698  for(int i = 0; i < n; i++)
699  for(int j = 0; j < m; j++)
700  {
701  mp.addPatch(BSplineSquare(r,lx + r*(T)(i) ,ly + r*(T)(j))) ;
702  }
703  mp.computeTopology();
704  return mp;
705 }
706 
707 
708 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
710 {
711  gsKnotVector<T> KV (0,1,0,2) ;
712  gsMatrix<T> C(4,2) ;
713  C << Box(0,0) , Box(1,0), Box(0,1),Box(1,0),
714  Box(0,0) , Box(1,1), Box(0,1),Box(1,1) ;
715 
716  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(C)));
717 }
718 
719 // The unit square represented as a tensor B-spline of degree \a deg
720 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
722 {
723  GISMO_ASSERT(deg>0,"Degree must be at least one.");
724  TensorBSpline2Ptr res = BSplineSquare(scale, 0.0, 0.0);
725  res->degreeElevate(deg-1);
726  return res;
727 }
728 
729 
730 template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
731 gsNurbsCreator<T>::BSplineCube( T const & r, T const & x,
732  T const & y, T const & z)
733 {
734  gsKnotVector<T> KV (0,1,0,2) ;
735  gsMatrix<T> C(8,3) ;
736  C << -0.5 , -0.5 , -0.5, 0.5 , -0.5 , -0.5
737  , -0.5 , 0.5 , -0.5, 0.5 , 0.5 , -0.5
738  , -0.5 , -0.5 , 0.5, 0.5 , -0.5 , 0.5
739  , -0.5 , 0.5 , 0.5, 0.5 , 0.5 , 0.5 ;
740  C *= r;
741  C.col(0).array() += x;
742  C.col(1).array() += y;
743  C.col(2).array() += z;
744 
745  return TensorBSpline3Ptr(new gsTensorBSpline<3,T>(KV,KV,KV, give(C)));
746 }
747 
748 
749 // Note: this can probably be removed once we have degree elevation for tensor B-splines.
750 //
752 template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
754 {
755  const int n = (deg + 1) * (deg + 1) * (deg + 1); // number of basis functions
756 
757  gsMatrix<T> C(n, 3);
758 
759  index_t r = 0;
760 
761  for (int k = 0; k <= deg; ++k)
762  for (int j = 0; j <= deg; ++j)
763  for (int i = 0; i <= deg; ++i)
764  {
765  C(r, 0) = ((T) i) / (T)(deg);
766  C(r, 1) = ((T) j) / (T)(deg);
767  C(r, 2) = ((T) k) / (T)(deg);
768  ++r;
769  }
770 
771  gsKnotVector<T> KV(0,1, 0, deg+1);
772  return TensorBSpline3Ptr(new gsTensorBSpline<3,T>(KV,KV,KV, give(C)));
773 }
774 
775 template<class T> gsMultiPatch<T>
776 gsNurbsCreator<T>::BSplineCubeGrid(int n, int m,int p,
777  T const & r,
778  T const & lx,
779  T const & ly,
780  T const & lz)
781 {
782  gsMultiPatch<T> mp;
783 
784  for(int i = 0; i < n; i++)
785  for(int j = 0; j < m; j++)
786  for(int k = 0; k < p; k++)
787  {
788  mp.addPatch(BSplineCube(r, r*(T)(0.5) + lx + r*(T)(i), r*(T)(0.5) + ly + r*(T)(j), r*(T)(0.5) + lz+r*(T)(k))) ;
789  }
790  mp.computeTopology();
791  return mp;
792 }
793 
794 
795 template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
796 gsNurbsCreator<T>::BSplineHalfCube( T const & r, T const & x,
797  T const & y, T const & z)
798 {
799  gsKnotVector<T> KV (0,1,0,2) ;
800  gsMatrix<T> C(8,3) ;
801  C << -0.5 , -0.5 , -0.5, 0.5 , -0.5 , -0.5
802  , -0.5 , 0.5 , -0.5, 0 , 0 , -0.5
803  , -0.5 , -0.5 , 0.5, 0.5 , -0.5 , 0.5
804  , -0.5 , 0.5 , 0.5, 0 , 0 , 0.5 ;
805  C *= r;
806  C.col(0).array() += x;
807  C.col(1).array() += y;
808  C.col(2).array() += z;
809 
810  return TensorBSpline3Ptr(new gsTensorBSpline<3,T>(KV,KV,KV, give(C)));
811 }
812 
813 template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
814 gsNurbsCreator<T>::NurbsCube( T const & r, T const & x,
815  T const & y, T const & z)
816 {
817  gsKnotVector<T> KV (0,1,0,2) ;
818  gsMatrix<T> C(8,3) ;
819  C << 0 , 0 , 0, r , 0 , 0 // Cube
820  , 0 , r , 0, r , r , 0
821  , 0 , 0 , r, r , 0 , r
822  , 0 , r , r, r , r , r ;
823 
824  C.col(0).array() += x;
825  C.col(1).array() += y;
826  C.col(2).array() += z;
827 
828  return TensorNurbs3Ptr(new gsTensorNurbs<3,T>(KV,KV,KV, give(C)));
829 }
830 
831 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
832 gsNurbsCreator<T>::NurbsQuarterAnnulus( T const & r0, T const & r1)
833 {
834  gsKnotVector<T> KVx (0,1,0,2) ;
835  gsKnotVector<T> KVy (0,1,0,3) ;
836  gsMatrix<T> C(6,2) ;
837  C << r0 , 0 , r1, 0
838  , r0 , r0 , r1, r1
839  , 0 , r0 , 0 , r1 ;
840 
841  // Set weights
842  gsMatrix<T> ww(6,1) ;
843  ww.setOnes();
844  ww.at(2)= 0.707106781186548 ;
845  ww.at(3)= 0.707106781186548 ;
846 
847  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(KVx,KVy, give(C), give(ww)));
848 }
849 
850 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
851 gsNurbsCreator<T>::NurbsAnnulus( T const & r0, T const & r1)
852 {
853  gsKnotVector<T> KVx (0,1,3,3,2) ;
854  gsKnotVector<T> KVy (0,1,0,2) ;
855  gsMatrix<T> C(18,2) ;
856 
857  C << r0, 0,
858  r0, r0,
859  0, r0,
860  -r0, r0,
861  -r0, 0,
862  -r0,-r0,
863  0,-r0,
864  r0,-r0,
865  r0, 0,
866  r1, 0,
867  r1, r1,
868  0, r1,
869  -r1, r1,
870  -r1, 0,
871  -r1,-r1,
872  0,-r1,
873  r1,-r1,
874  r1, 0;
875  // C *= r;
876 
877  // C.col(0).array() += x;
878  // C.col(1).array() += y;
879 
880  gsMatrix<T> ww(18,1) ;
881  ww<< 1, 0.707106781186548, 1, 0.707106781186548,1, 0.707106781186548,1, 0.707106781186548, 1, 1, 0.707106781186548, 1, 0.707106781186548,1, 0.707106781186548,1, 0.707106781186548, 1 ;
882 
883  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(KVx,KVy, give(C), give(ww)));
884 }
885 
887 template<class T> typename gsNurbsCreator<T>::GeometryPtr
889 {
890  GeometryPtr quann = gsNurbsCreator<T>::NurbsQuarterAnnulus();
891 
892  gsKnotVector<T> KV1(0,1, 0, 2);
893  gsKnotVector<T> KV2(0,1, deg-2, deg+1);
894 
896  const gsMatrix<T> pts = tbsp.anchors();
897  return tbsp.interpolateData(quann->eval(pts),pts);
898 }
899 
900 template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
902 {
903  return TensorNurbs3Ptr(); //TODO
904 }
905 
906 /*
907 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
908 gsNurbsCreator<T>::NurbsQuarterAnnulusMixedWithLShape()
909 {
910  gsKnotVector<T> KVx (0,1,0,2) ;
911  gsKnotVector<T> KVy (0,1,0,4) ;
912 
913  //gsKnotVector<T> KVx(0,1,1,2,1);
914  //gsKnotVector<T> KVy(0,1,0,2);
915 
916  gsMatrix<T> C(8,2) ;
917  C << -1.0,1.0,
918  -1.0,0.0,
919  -1.0,-1.0,
920  0.0,-1.0,
921  1.0,-1.0,
922  0.0,1.0,
923  0.0,0.0,
924  1.0,0.0;
925 
926  // Set weights
927  gsMatrix<T> ww(8,1) ;
928  ww.setOnes();
929  ww.at(2)= 0.707106781186548 ;
930 
931  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(KVx, KVy, give(C), give(ww)));
932 }
933 
935 template<class T> typename gsNurbsCreator<T>::GeometryPtr
936 gsNurbsCreator<T>::BSplineQuarterAnnulusMixedWithLShape(int const & deg) {
937  GeometryPtr quann = gsNurbsCreator<T>::NurbsQuarterAnnulusMixedWithLShape();
938 
939  gsKnotVector<T> KV1(0, 1, 0, 2);
940  gsKnotVector<T> KV2(0, 1, deg - 2, deg + 1);
941 
942  gsTensorBSplineBasis<2, T> tbsp(new gsBSplineBasis<T>(KV1), new gsBSplineBasis<T>(KV2));
943  const gsMatrix<T> pts = tbsp.anchors();
944  return GeometryPtr(tbsp.interpolateData(quann->eval(pts), pts));
945 }
946 */
947 
948 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
950 {
951  gsKnotVector<T> KVx (0,1,0,2) ;
952  gsKnotVector<T> KVy (0,1,0,3) ;
953 
954  gsMatrix<T> C(6,2) ;
955  C << r0 , 0 , r1, 0
956  , r0 , r0 , r1, r1
957  , 0 , r0 , 0 , r1 ;
958 
959  //gsMatrix<T> C(9,2) ;
960  // C << r0 , 0 , (r0+r1)/2, 0 , r1, 0
961  // , r0 , r0 , (r0+r1)/2, (r0+r1)/2 , r1, r1
962  // , 0 , r0 , 0 , (r0+r1)/2 , 0 , r1 ;
963 
964  //return new gsTensorBSpline<2,T>(KVy,KVy,2,2, C);
965  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KVx,KVy, give(C)));
966 }
967 
968 
969 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
970 gsNurbsCreator<T>::NurbsSphere( T const & r, T const & x,
971  T const & y, T const & z)
972 {
973  gsKnotVector<T> KV1 (0,1,1,3,2) ;
974  gsKnotVector<T> KV2 (0,1,3,3,2) ;
975  gsMatrix<T> C(45,3) ;
976  C<<
977  2, 0, 0, 2, 2, 0, 0, 2, 0,-2, 2, 0,-2, 0, 0,
978  2, 0, 2, 2, 2, 2, 0, 2, 2,-2, 2, 2,-2, 0, 2,
979  0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2,
980  2, 0, 2, 2,-2, 2, 0,-2, 2,-2,-2, 2,-2, 0, 2,
981  2, 0, 0, 2,-2, 0, 0,-2, 0,-2,-2, 0,-2, 0, 0,
982  2, 0,-2, 2,-2,-2, 0,-2,-2,-2,-2,-2,-2, 0,-2,
983  0, 0,-2, 0, 0,-2, 0, 0,-2, 0, 0,-2, 0, 0,-2,
984  2, 0,-2, 2, 2,-2, 0, 2,-2,-2, 2,-2,-2, 0,-2,
985  2, 0, 0, 2, 2, 0, 0, 2, 0,-2, 2, 0,-2, 0, 0;
986 
987  C *= r/2.;
988 
989  gsMatrix<T> W(45,1) ;
990  W << 1, 0.707106781186548, 1, 0.707106781186548, 1,
991  0.707106781186548, 0.5, 0.707106781186548, 0.5, 0.707106781186548,
992  1, 0.707106781186548, 1, 0.707106781186548, 1,
993  0.707106781186548, 0.5, 0.707106781186548, 0.5, 0.707106781186548,
994  1, 0.707106781186548, 1, 0.707106781186548, 1,
995  0.707106781186548, 0.5, 0.707106781186548, 0.5, 0.707106781186548,
996  1, 0.707106781186548, 1, 0.707106781186548, 1,
997  0.707106781186548, 0.5, 0.707106781186548, 0.5, 0.707106781186548,
998  1, 0.707106781186548, 1, 0.707106781186548, 1;
999 
1000  C.col(0).array() += x;
1001  C.col(1).array() += y;
1002  C.col(2).array() += z;
1003 
1004  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(KV1,KV2, give(C), give(W)));
1005 }
1006 
1007 
1008 template<class T> typename gsNurbsCreator<T>::NurbsPtr
1009 gsNurbsCreator<T>::NurbsCircle( T const & r, T const & x, T const & y)
1010 {
1011  gsKnotVector<T> KV2 (0,1,3,3,2) ;
1012  gsMatrix<T> C(9,2) ;
1013  C << 1, 0,
1014  1, 1,
1015  0, 1,
1016  -1, 1,
1017  -1, 0,
1018  -1,-1,
1019  0,-1,
1020  1,-1,
1021  1, 0;
1022  C *= r;
1023 
1024  C.col(0).array() += x;
1025  C.col(1).array() += y;
1026 
1027  gsMatrix<T> ww(9,1) ;
1028  ww<< 1, 0.707106781186548, 1, 0.707106781186548,1, 0.707106781186548,1, 0.707106781186548, 1 ;
1029 
1030  return NurbsPtr(new gsNurbs<T>(KV2, give(ww), give(C)));
1031 }
1032 
1033 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1034 gsNurbsCreator<T>::BSplineFatCircle( T const & r, T const & x, T const & y)
1035 {
1036  gsKnotVector<T> KV2 (0,1,3,3,2) ;
1037  gsMatrix<T> C(9,2) ;
1038  C << 1, 0,
1039  1, 1,
1040  0, 1,
1041  -1, 1,
1042  -1, 0,
1043  -1,-1,
1044  0,-1,
1045  1,-1,
1046  1, 0;
1047  C *= r;
1048 
1049  C.col(0).array() += x;
1050  C.col(1).array() += y;
1051 
1052  return BSplinePtr(new gsBSpline<T>(KV2, give(C)));
1053 }
1054 
1055 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1056 gsNurbsCreator<T>::BSplineFatDisk (T const & r, T const & x, T const & y)
1057 {
1058  gsKnotVector<T> KV (0,1,0,3) ;
1059  gsMatrix<T> C(9,2) ;
1060  C << 0, -r , r,-r , r, 0
1061  ,-r, -r , 0, 0 , r ,r
1062  ,-r , 0 , -r, r , 0 ,r ;
1063 
1064  C.col(0).array() += x;
1065  C.col(1).array() += y;
1066 
1067  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(C)));
1068 }
1069 
1070 template<class T> typename gsNurbsCreator<T>::NurbsPtr
1071 gsNurbsCreator<T>::NurbsCurve1 (T const & r, T const & x, T const & y)
1072 {
1073  gsKnotVector<T> KV2 (0,4,3,3,2) ;
1074  KV2.uniformRefine();
1075  gsMatrix<T> C(13,2) ;
1076  C << 0, -1,
1077  0.5, -1,
1078  1, -0.5,
1079  1, 0,
1080  1, 0.5,
1081  0.5, 1,
1082  0, 1,
1083  -0.5, 1,
1084  -1, 0.5,
1085  -1, 0,
1086  -1, -0.5,
1087  -0.5, -1,
1088  0, -1;
1089  C *= r;
1090 
1091  C.col(0).array() += x;
1092  C.col(1).array() += y;
1093 
1094  gsMatrix<T> ww(13,1) ;
1095  ww<< 1, 0.853553, 0.853553, 1, 0.853553, 0.853553, 1, 0.853553,
1096  0.853553, 1, 0.853553, 0.853553, 1;
1097 
1098  gsNurbs<T> * nn = new gsNurbs<T>(KV2, give(C), give(ww));
1099  // gsDebug<<" nurbs:\n " <<* nn << std::endl;
1100  // nn->uniformRefine();
1101  // gsDebug<<" coefs:\n " <<* nn->coefs() << std::endl;
1102  // gsDebug<<" weights:\n " <<* nn->weights() << std::endl;
1103 
1104 
1105  return NurbsPtr(nn);
1106 }
1107 
1108 
1109 template<class T> typename gsNurbsCreator<T>::NurbsPtr
1110 gsNurbsCreator<T>::NurbsCurve2 (T const & r, T const & x, T const & y)
1111 {
1112  gsKnotVector<T> kv(0,4,3,3,2);
1113  gsMatrix<T> C(9,2);
1114  C << 0, -2 , 0.5,-0.5 , 2, 0
1115  ,-2, -2 , 0, 0 , 0.5 ,0.5
1116  ,-2 , 0 , -0.5, 0.5 , 0 ,-2 ;
1117 
1118  C *= r;
1119 
1120  C.col(0).array() += x;
1121  C.col(1).array() += y;
1122 
1123  gsMatrix<T> ww( 9, 1 ) ;
1124  ww(0)= 1;
1125  ww(1)= 0.20 ;
1126  ww(2)= 1;
1127  ww(3)= 0.707106781186548 ;
1128  ww(4)= 0.5 ;
1129  ww(5)= 0.20 ;
1130  ww(6)= 1;
1131  ww(7)= 0.707106781186548 ;
1132  ww(8)= 1 ;
1133 
1134  return NurbsPtr(new gsNurbs<T>(kv, give(C), give(ww)));
1135 }
1136 
1137 
1138 template<class T> typename gsNurbsCreator<T>::NurbsPtr
1139 gsNurbsCreator<T>::NurbsBean(T const &, T const & x, T const & y)
1140 {
1141  gsKnotVector<T> kv(0,1,12,3,1,2);
1142  gsMatrix<T> C(15,2);
1143  C << 1,0,
1144  1,1,
1145  0,2,
1146  0,3,
1147  1,4,
1148  1.5,5.2,
1149  0.5,6,
1150  -1,5,
1151  -1.5,3,
1152  -2,1,
1153  -2,-1,
1154  -1,-2,
1155  0,-2,
1156  1,-1,
1157  1,0;
1158 
1159  C.col(0).array() += x;
1160  C.col(1).array() += y;
1161 
1162  gsMatrix<T> ww( 15, 1 ) ;
1163  ww.setOnes();
1164  return NurbsPtr(new gsNurbs<T>(kv, give(C), give(ww)));
1165 }
1166 
1167 
1168 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1169 gsNurbsCreator<T>::BSplineE (T const &, T const & x, T const & y)
1170 {
1171  gsKnotVector<T> kv(0,1,22,4,1,3);
1172  gsMatrix<T> C(26,2);
1173  C << -2,0,
1174  -2,1,
1175  -2,2,
1176  -1,3,
1177  2,3.3,
1178  2.5,2.8,
1179  3,2,
1180  2.5,1.5,
1181  1, 1.5,
1182  0.5, 1.2,
1183  1,1,
1184  2,1,
1185  3,0.5, 2.5,-0.5,
1186  0.5, -0.5,
1187  0.5,-1.5,
1188  1, -1.7,
1189  2, -1.5,
1190  3, -1.5,
1191  3.3, -2.2,
1192  3, -3,
1193  0, -3.3,
1194  -1, -3,
1195  -2, -2,
1196  -2, -1,
1197  -2,0;
1198 
1199  C.col(0).array() += x;
1200  C.col(1).array() += y;
1201 
1202  return BSplinePtr(new gsBSpline<T>(kv, give(C)));
1203 }
1204 
1205 template<class T> typename gsNurbsCreator<T>::NurbsPtr
1206 gsNurbsCreator<T>::NurbsAmoebaFull(T const &, T const & x, T const & y)
1207 {
1208  gsKnotVector<T> kv(0,1,19,3,1,2);
1209  gsMatrix<T> C(22,2);
1210  C << -10,-2,
1211  -10,1,
1212  -9,2,
1213  -6.8,2.1,
1214  -7,4,
1215  -5,6.5,
1216  -3,6,
1217  -0.5,3,
1218  0.5,3.2,
1219  4,6,
1220  7,6,
1221  8,3,
1222  5,0,
1223  3.8,-1,
1224  5,-2,
1225  6,-6,
1226  2,-8,
1227  -2,-6,
1228  -2,-2,
1229  -6,-3,
1230  -10,-3,
1231  -10,-2;
1232 
1233  C.col(0).array() += x;
1234  C.col(1).array() += y;
1235 
1236  gsMatrix<T> ww(22, 1 ) ;
1237  ww.setOnes();
1238  return NurbsPtr(new gsNurbs<T>(kv, give(ww), give(C)));
1239 }
1240 
1241 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1242 gsNurbsCreator<T>::BSplineLineSegment(gsMatrix<T> const & p0, gsMatrix<T> const & p1 )
1243 {
1244  gsKnotVector<T> kv(0,1,0,2,1,1);
1245  gsMatrix<T> C(2,2);
1246 
1247  C.row(0).noalias() = p0.transpose();
1248  C.row(1).noalias() = p1.transpose();
1249  return BSplinePtr(new gsBSpline<T>(kv, give(C)));
1250 }
1251 
1252 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1253 gsNurbsCreator<T>::BSplineSegment(T const u0, T const u1)
1254 {
1255  gsKnotVector<T> kv(u0, u1, 0, 2);
1256  gsBSplineBasis<T> bsb(kv);
1257  return BSplinePtr(new gsBSpline<T>(bsb, bsb.anchors().transpose()) );
1258 }
1259 
1261 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1263 {
1264  // create knot vector [0,0, 0.5, 1,1]
1265  gsKnotVector<T> tK1(0,1,1,2,1);
1266  // create knot vector [0,0, 1,1]
1267  gsKnotVector<T> tK2(0,1,0,2);
1268 
1269  gsMatrix<T> C(6,2);
1270 
1271  C <<-1.0,1.0,
1272  -1.0,-1.0,
1273  1.0,-1.0,
1274  0.0,1.0,
1275  0.0,0.0,
1276  1.0,0.0;
1277 
1278  C *= r;
1279 
1280  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(tK1,tK2, give(C)));
1281 }
1282 
1283 
1286 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1288 {
1289  // create knot vector [0,0,0, 0.5,0.5, 1,1,1]
1290  gsKnotVector<T> tK1(0,1,1,3,2);
1291  // create knot vector [0,0,0, 1,1,1]
1292  gsKnotVector<T> tK2(0,1,0,3);
1293 
1294  gsMatrix<T> C(15,2);
1295 
1296  C << -1.0,1.0,
1297  -1.0,0.0,
1298  -1.0,-1.0,
1299  0.0,-1.0,
1300  1.0,-1.0,
1301  -0.6,1.0,
1302  -0.55,0.0,
1303  -0.5,-0.5,
1304  0.0,-0.55,
1305  1.0,-0.6,
1306  0.0,1.0,
1307  0.0,0.5,
1308  0.0,0.0,
1309  0.5,0.0,
1310  1.0,0.0;
1311 
1312  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(tK1,tK2, give(C)));
1313 }
1314 
1315 
1318 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1320 {
1321  // create knot vector [0,0,0, 0.25,0.5,0.75 1,1,1]
1322  gsKnotVector<T> tK1(0,1,3,3);
1323  // create knot vector [0,0,0, 0.5, 1,1,1]
1324  gsKnotVector<T> tK2(0,1,1,3);
1325 
1326  gsMatrix<T> C(24,2);
1327 
1328  C << -1.0, 1.0,
1329  -1.0, 0.2,
1330  -1.0, -1.0,
1331  -1.0, -1.0,
1332  0.2, -1.0,
1333  1.0, -1.0,
1334  -0.75, 1.0,
1335  -0.7, 0.35,
1336  -0.6, -0.3,
1337  -0.3, -0.6,
1338  0.35, -0.7,
1339  1.0, -0.75,
1340  -0.3, 1.0,
1341  -0.3, 0.5,
1342  -0.2, -0.05,
1343  -0.05, -0.2,
1344  0.5, -0.3,
1345  1.0, -0.3,
1346  0.0, 1.0,
1347  0.0, 0.5,
1348  0.0, 0.0,
1349  0.0, 0.0,
1350  0.5, 0.0,
1351  1.0, 0.0;
1352 
1353  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(tK1,tK2, give(C)));
1354 }
1355 
1356 template<class T> gsMultiPatch<T>
1358 {
1359  gsMultiPatch<T> mp;
1360 
1361  TensorBSpline2Ptr patch1 = BSplineSquare(0.5, 0.0, 0.0);
1362  patch1->degreeElevate();
1363  mp.addPatch( give(patch1) ) ;
1364 
1365  TensorBSpline2Ptr patch2 = BSplineSquare(0.5, 0, 0.5);
1366  patch2->degreeElevate();
1367  mp.addPatch( give(patch2) ) ;
1368 
1369  TensorBSpline2Ptr patch3 = BSplineSquare(0.5, 0.5, 0);
1370  patch3->degreeElevate();
1371  mp.addPatch( give(patch3) ) ;
1372 
1373  mp.computeTopology();
1374  return mp;
1375 }
1376 
1377 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1378 gsNurbsCreator<T>::BSplineAmoeba(T const &, T const & x, T const & y)
1379 {
1380  gsKnotVector<T> kv(0,1,19,3,1,2);
1381  gsMatrix<T> C(22,2);
1382 
1383  C << -10,-2,
1384  -10,-1,
1385  -9,2,
1386  -6.8,2.1,
1387  -7,4,
1388  -5,6.5,
1389  -3,6,
1390  -0.5,3,
1391  0.5,3.2,
1392  4,6,
1393  7,6,
1394  8,3,
1395  5,0,
1396  3.8,-1,
1397  5,-2,
1398  6,-6,
1399  2,-8,
1400  -2,-6,
1401  -2,-2,
1402  -6,-3,
1403  -10,-3,
1404  -10,-2;
1405 
1406  C /= 2;
1407 
1408  C.col(0).array() += x;
1409  C.col(1).array() += y;
1410 
1411  gsBSpline<T> *B =new gsBSpline<T>(kv, give(C));
1412  B->reverse();
1413  return BSplinePtr(B);
1414 }
1415 
1416 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1417 gsNurbsCreator<T>::BSplineAmoebaBig(T const &, T const & x, T const & y)
1418 {
1419  gsKnotVector<T> kv(0,1,19,3,1,2);
1420  gsMatrix<T> C(22,2);
1421 
1422  C << -10,-2,
1423  -10,-1,
1424  -9,2,
1425  -6.8,2.1,
1426  -7,4,
1427  -5,6.5,
1428  -3,6,
1429  -0.5,3,
1430  0.5,3.2,
1431  4,6,
1432  7,6,
1433  8,3,
1434  5,0,
1435  3.8,-1,
1436  5,-2,
1437  6,-6,
1438  2,-8,
1439  -2,-6,
1440  -2,-2,
1441  -6,-3,
1442  -10,-3,
1443  -10,-2;
1444 
1445  C.col(0).array() += x;
1446  C.col(1).array() += y;
1447 
1448  gsBSpline<T> *B =new gsBSpline<T>(kv, give(C));
1449  B->reverse();
1450  return BSplinePtr(B);
1451 }
1452 
1453 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1454 gsNurbsCreator<T>::BSplineAustria(T const &, T const & x, T const & y)
1455 {
1456  gsKnotVector<T> kv(0,1,31,3,1,2);
1457  gsMatrix<T> C(34,2);
1458 
1459  C << 0.3, 2.5,
1460  0.7, 2.7,
1461  1 , 3,
1462  1.5, 3,
1463  2, 2.5,
1464  2.7, 2.7,
1465  3.2, 2.2,
1466  3.2, 1.5,
1467  3, 0.8,
1468  2.7, 0.6,
1469  2.5, 0,
1470  1.8, -0.6,
1471  0.5, -1.3,
1472  0, -1.5,
1473  -1.4, -1.4,
1474  -2, -1.2,
1475  -2.5, -0.8,
1476  -3, -0.4,
1477  -4, -0.5,
1478  -5, -0.7,
1479  -5.5, -0.5,
1480  -6, -0.3,
1481  -6.1, 0.3,
1482  -5.6, 0.2,
1483  -5.4, 0,
1484  -5, 0.3,
1485  -4.5, 0,
1486  -3, 0.5,
1487  -2.5, 0.4,
1488  -1.8, 0.5,
1489  -2, 1.5,
1490  -1.6, 1.8,
1491  -0.7, 2.5,
1492  0.3, 2.5;
1493 
1494  C.col(0).array() += x;
1495  C.col(1).array() += y;
1496 
1497  gsBSpline<T> *B =new gsBSpline<T>(kv, give(C));
1498  B->reverse();
1499  return BSplinePtr(B);
1500 }
1501 
1502 
1503 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1504 gsNurbsCreator<T>::BSplineFish(T const &, T const & x, T const & y)
1505 {
1506  gsKnotVector<T> kv(0,1,13,3,1,2);
1507  gsMatrix<T> C(16,2);
1508 
1509  C << -3,0,
1510  0,-3,
1511  2,-3,
1512  2.5,-2.5,
1513  4,-2.2,
1514  6,-2,
1515  6.5,-1,
1516  5.5,-0.5,
1517  5.5, 0.5,
1518  6,1,
1519  5.5,2,
1520  4.2,2,
1521  3,1.5,
1522  2,3,
1523  0,3,
1524  -3,0;
1525  C.col(0).array() += x;
1526  C.col(1).array() += y;
1527 
1528  gsBSpline<T> *B =new gsBSpline<T>(kv, give(C));
1529  return BSplinePtr(B);
1530 }
1531 
1532 template<class T> typename gsNurbsCreator<T>::BSplinePtr
1533 gsNurbsCreator<T>::BSplineAmoeba3degree(T const &, T const & x, T const & y)
1534 {
1535  gsKnotVector<T> kv(0,1,18,4,1,3);
1536  gsMatrix<T> C(22,2);
1537 
1538 
1539  C << -5, -1,
1540  -5,0.5,
1541  -4.5, 1,
1542  -3.4, 1.05,
1543  -3.5, 2,
1544  -2.5, 3.25,
1545  -1.5, 3,
1546  -0.25, 1.5,
1547  0.25 ,1.6,
1548  2, 3,
1549  3.5, 3,
1550  4, 1.5,
1551  2.5, 0,
1552  1.9 ,-0.5 ,
1553  2.5, -1,
1554  3, -3,
1555  1, -4,
1556  -1, -3,
1557  -1, -1,
1558  -3, -1.5,
1559  -5, -1.5,
1560  -5, -1;
1561 
1562  C.col(0).array() += x;
1563  C.col(1).array() += y;
1564 
1565  gsBSpline<T> *B =new gsBSpline<T>(kv, give(C));
1566  B->reverse();
1567  return BSplinePtr(B);
1568 }
1569 
1570 
1571 template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
1572 gsNurbsCreator<T>::NurbsDisk(T const & r, T const & x, T const & y)
1573 {
1574  gsKnotVector<T> kv(0,1,0,3);
1575  gsMatrix<T> C(9,2);
1576 
1577  C << 0, -2 , 2,-2 , 2, 0
1578  ,-2, -2 , 0, 0 , 2 ,2
1579  ,-2 , 0 , -2, 2 , 0 ,2 ;
1580 
1581  C *= r;
1582 
1583  C.col(0).array() += x;
1584  C.col(1).array() += y;
1585 
1586  gsMatrix<T> ww(9, 1 ) ;
1587  ww(0)= 1;
1588  ww(1)= 0.707106781186548 ;
1589  ww(2)= 1;
1590  ww(3)= 0.707106781186548 ;
1591  ww(4)= 0.5 ;
1592  ww(5)= 0.707106781186548 ;
1593  ww(6)= 1;
1594  ww(7)= 0.707106781186548 ;
1595  ww(8)= 1 ;
1596 
1597  return TensorNurbs2Ptr(new gsTensorNurbs<2,T>(kv,kv, give(C), give(ww)));
1598 }
1599 
1600 
1601 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1602 gsNurbsCreator<T>::NurbsQrtPlateWHoleC0()
1603 {
1604  // SK:
1605  // NOTE: This is still a B-SPLINE plate-with-hole!!!
1606  // The circular part is NOT exact.
1607  // TODO: Make a real NURBS geometry out of this.
1608 
1609  gsKnotVector<T> kv1(0,1,1,3,2);
1610  gsKnotVector<T> kv2(0,1,0,3);
1611  gsMatrix<T> C(15,2);
1612 
1613  C << -1, 0,
1614  -1, sqrt(2.0)-1,
1615  -1/sqrt(2.0), 1/sqrt(2.0),
1616  1-sqrt(2.0), 1,
1617  0, 1,
1618  -2.5, 0,
1619  -2.5, 0.75,
1620  -1.5, 1.5,
1621  -0.75, 2.5,
1622  0, 2.5,
1623  -4, 0,
1624  -4, 2,
1625  -4, 4,
1626  -2, 4,
1627  0, 4;
1628 
1629  //return new gsTensorNurbs<2,T>(kv,kv, give(C), give(ww));
1630  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(kv1,kv2, give(C)));
1631 
1632 }
1633 
1635 template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1637  T const & W)
1638 {
1639  gsKnotVector<T> KV (0,1,0,2) ;
1640  gsMatrix<T> C(4,2) ;
1641 
1642  C.col(0) << 0 , 0 , 0.5*W, W;
1643  C.col(1) << H , 0 , 0.5*H, 0 ;
1644 
1645  return TensorBSpline2Ptr(new gsTensorBSpline<2,T>(KV,KV, give(C)));
1646 }
1647 
1649 template<class T> gsMultiPatch<T>
1651  T const & R0,
1652  T const & R1)
1653 {
1654  GISMO_ENSURE(N>2,"Star must have at least 3 points.");
1655 
1656  const T pi = 3.1415926535897932384626433832795;
1657  const T theta = 2*pi/N;
1658  gsKnotVector<T> KV(0,1,0,2);
1659  gsMatrix<T> coefs(4,2);
1660  coefs<< 0, 0,
1661  R1*math::cos(pi/2-theta/2), R1*math::sin(pi/2-theta/2),
1662  -R1*math::cos(pi/2-theta/2), R1*math::sin(pi/2-theta/2),
1663  0, R0;
1664 
1665  gsTensorBSpline<2,T> bspline(KV,KV,coefs);
1666  gsMultiPatch<T> result;
1667  for (index_t p=0; p!=N; p++)
1668  {
1669  result.addPatch(bspline);
1670  bspline = *(rotate2D(bspline,theta*360/(2*pi)));
1671  }
1672  return result;
1673 }
1674 
1675 } // namespace gismo
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry&lt;T&gt;::uPtr.
Definition: gsMultiPatch.hpp:210
Class gsNurbsCreator provides some simple examples of Nurbs Geometries.
Definition: gsNurbsCreator.h:36
static TensorNurbs2Ptr NurbsAnnulus(T const &r0=1, T const &r1=2)
Exact full annulus using NURBS with inner radius r0 and outer radius r1.
Definition: gsNurbsCreator.hpp:851
A NURBS function of one argument, with arbitrary target dimension.
Definition: gsNurbs.h:39
static TensorNurbs3Ptr NurbsCube(T const &r=1, T const &x=0, T const &y=0, T const &z=0)
Cube of side r, with lower left corner at (x,y,z) using NURBS.
Definition: gsNurbsCreator.hpp:814
static TensorNurbs2Ptr NurbsQuarterAnnulus(T const &r0=1, T const &r1=2)
Exact annulus using NURBS with inner radius r0 and outer radius r1.
Definition: gsNurbsCreator.hpp:832
Represents a NURBS curve/function with one parameter.
static gsMultiPatch< T > BSplineStar(index_t const &N=3, T const &R0=1, T const &R1=0.5)
Makes a star with N patches, outer radius R0 and inner radius R1.
Definition: gsNurbsCreator.hpp:1650
static TensorBSpline2Ptr BSplineFatDisk(T const &r=1, T const &x=0, T const &y=0)
Inexact disk using B-splines.
Definition: gsNurbsCreator.hpp:1056
#define short_t
Definition: gsConfig.h:35
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition: gsTensorBSpline.h:44
A tensor product Non-Uniform Rational B-spline function (NURBS) of parametric dimension d...
Definition: gsTensorNurbs.h:40
Represents a tensor-product B-spline patch.
S give(S &x)
Definition: gsMemory.h:266
static TensorBSpline2Ptr BSplineLShape_p1(T r=(T)(1))
L-Shaped domain represented as a tensor B-spline of degree 1.
Definition: gsNurbsCreator.hpp:1262
static gsMultiPatch< T > BSplineSquareGrid(int n, int m, T const &r=1, T const &lx=0, T const &ly=0)
Definition: gsNurbsCreator.hpp:691
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
Represents a tensor-product NURBS patch.
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
static BSplinePtr BSplineFatCircle(T const &r=(T)(1), T const &x=0, T const &y=0)
Inexact circle using B-splines.
Definition: gsNurbsCreator.hpp:1034
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
memory::unique_ptr< gsGeometry< T > > interpolateData(gsMatrix< T > const &vals, gsMatrix< T > const &pts) const
Applies interpolation given the parameter values pts and values vals.
Definition: gsBasis.hpp:217
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition: gsMatrix.h:211
static TensorBSpline2Ptr BSplineRectangle(T const &low_x=0, T const &low_y=0, T const &upp_x=1, T const &upp_y=1, T const &turndeg=0)
2d-rectange [low_x,upp_x] x [low_y,upp_y], rotated by turndeg degrees.
Definition: gsNurbsCreator.hpp:449
static TensorBSpline3Ptr BSplineCube(T const &r=1, T const &x=0, T const &y=0, T const &z=0)
Cube of side r, with lower left corner at (x,y,z)
Definition: gsNurbsCreator.hpp:731
static GeometryPtr BSplineQuarterAnnulus(const short_t &deg=2)
Inexact annulus using B-splines.
Definition: gsNurbsCreator.hpp:888
gsMatrix< T > anchors() const
Returns the anchor points that represent the members of the basis. There is exactly one anchor point ...
Definition: gsBasis.h:437
Provides declaration of the MultiPatch class.
static TensorBSpline2Ptr BSplineFatQuarterAnnulus(T const &r0=1, T const &r1=2)
Definition: gsNurbsCreator.hpp:949
static NurbsPtr NurbsCircle(T const &r=(T)(1), T const &x=0, T const &y=0)
Circle using NURBS.
Definition: gsNurbsCreator.hpp:1009
static gsMultiPatch< T > BSplineLShapeMultiPatch_p2()
Definition: gsNurbsCreator.hpp:1357
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
static TensorBSpline2Ptr BSplineSquareDeg(short_t deg, T scale=(T)(1))
The unit square represented as a tensor B-spline of degree deg.
Definition: gsNurbsCreator.hpp:721
Represents a B-spline curve/function with one parameter.
static TensorNurbs2Ptr NurbsArcTrapezium(T const &Lbot=1, T const &Ltop=0.5, T const &H=1, T const &d=0, T const &turndeg=0)
2d-trapezium
Definition: gsNurbsCreator.hpp:640
static TensorBSpline2Ptr BSplineTriangle(T const &H=1, T const &W=1)
Makes a Isosceles triangle with height H and width W.
Definition: gsNurbsCreator.hpp:1636
Class for representing a knot vector.
Definition: gsKnotVector.h:79
static TensorBSpline2Ptr BSplineLShape_p2C1()
Definition: gsNurbsCreator.hpp:1319
static TensorNurbs2Ptr NurbsSphere(T const &r=1, T const &x=0, T const &y=0, T const &z=0)
Sphere using NURBS.
Definition: gsNurbsCreator.hpp:970
static TensorBSpline2Ptr BSplineTrapezium(T const &Lbot=1, T const &Ltop=0.5, T const &H=1, T const &d=0, T const &turndeg=0)
Rectangle described by the identity mapping over the given parameter domain, using tensor product B-s...
Definition: gsNurbsCreator.hpp:539
static TensorBSpline2Ptr BSplineLShape_p2C0()
Definition: gsNurbsCreator.hpp:1287
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition: gsMultiPatch.hpp:366