G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsNurbsCreator.hpp
Go to the documentation of this file.
1
14#pragma once
15
16#include <gsCore/gsMultiPatch.h>
17
20#include <gsNurbs/gsNurbs.h>
21#include <gsNurbs/gsBSpline.h>
22#include <math.h>
23
24namespace gismo
25{
26
27/*
28 @brief Class gsNurbsCreator provides some simple examples of Nurbs Geometries
29*/
30
31template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
32gsNurbsCreator<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
54template <class T>
55void 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
70template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
71gsNurbsCreator<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
84template <class T>
85void 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
93template<class T>
94void 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
100template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
101gsNurbsCreator<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
112template <class T>
113void 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
121template <class T>
122void 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
135template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
136gsNurbsCreator<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
146template <class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
147gsNurbsCreator<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
158template <class T>
159void 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
167template <class T>
168void 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
177template <class T>
178void 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
184template <class T>
185void 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
191template <typename T>
192void 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
213template <typename T>
214gsMultiPatch<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
259template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
260gsNurbsCreator<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
287template<class T> typename gsNurbsCreator<T>::TensorBSpline4Ptr
288gsNurbsCreator<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
316template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
317gsNurbsCreator<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
348template<class T> typename gsNurbsCreator<T>::TensorNurbs4Ptr
349gsNurbsCreator<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
437template<class T> typename gsNurbsCreator<T>::BSplinePtr
438gsNurbsCreator<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
448template<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 */
505template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
506gsNurbsCreator<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
538template<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
555template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
556gsNurbsCreator<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 */
586template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
587gsNurbsCreator<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
639template<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
657template<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
690template<class T> gsMultiPatch<T>
692 T const & r,
693 T const & lx,
694 T const & ly)
695{
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
708template<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
720template<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
730template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
731gsNurbsCreator<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 + 0.5;
742 C.col(1).array() += y + 0.5;
743 C.col(2).array() += z + 0.5;
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//
752template<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
775template<class T> gsMultiPatch<T>
776gsNurbsCreator<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{
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
795template<class T> typename gsNurbsCreator<T>::TensorBSpline3Ptr
796gsNurbsCreator<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
813template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
814gsNurbsCreator<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
831template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
832gsNurbsCreator<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
850template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
851gsNurbsCreator<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
887template<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
900template<class T> typename gsNurbsCreator<T>::TensorNurbs3Ptr
902{
903 return TensorNurbs3Ptr(); //TODO
904}
905
906/*
907template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
908gsNurbsCreator<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
935template<class T> typename gsNurbsCreator<T>::GeometryPtr
936gsNurbsCreator<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
948template<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
969template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
970gsNurbsCreator<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
1008template<class T> typename gsNurbsCreator<T>::NurbsPtr
1009gsNurbsCreator<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
1033template<class T> typename gsNurbsCreator<T>::BSplinePtr
1034gsNurbsCreator<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
1055template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1056gsNurbsCreator<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
1070template<class T> typename gsNurbsCreator<T>::NurbsPtr
1071gsNurbsCreator<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
1109template<class T> typename gsNurbsCreator<T>::NurbsPtr
1110gsNurbsCreator<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
1138template<class T> typename gsNurbsCreator<T>::NurbsPtr
1139gsNurbsCreator<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
1168template<class T> typename gsNurbsCreator<T>::BSplinePtr
1169gsNurbsCreator<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
1205template<class T> typename gsNurbsCreator<T>::NurbsPtr
1206gsNurbsCreator<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
1241template<class T> typename gsNurbsCreator<T>::BSplinePtr
1242gsNurbsCreator<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
1252template<class T> typename gsNurbsCreator<T>::BSplinePtr
1253gsNurbsCreator<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
1261template<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
1286template<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
1318template<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
1356template<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
1377template<class T> typename gsNurbsCreator<T>::BSplinePtr
1378gsNurbsCreator<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
1416template<class T> typename gsNurbsCreator<T>::BSplinePtr
1417gsNurbsCreator<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
1453template<class T> typename gsNurbsCreator<T>::BSplinePtr
1454gsNurbsCreator<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
1503template<class T> typename gsNurbsCreator<T>::BSplinePtr
1504gsNurbsCreator<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
1532template<class T> typename gsNurbsCreator<T>::BSplinePtr
1533gsNurbsCreator<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
1571template<class T> typename gsNurbsCreator<T>::TensorNurbs2Ptr
1572gsNurbsCreator<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, -1 , 1,-1 , 1, 0
1578 ,-1, -1 , 0, 0 , 1 ,1
1579 ,-1 , 0 , -1, 1 , 0 ,1 ;
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
1601template<class T> typename gsNurbsCreator<T>::TensorBSpline2Ptr
1602gsNurbsCreator<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
1635template<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
1649template<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
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A B-spline function of one argument, with arbitrary target dimension.
Definition gsBSpline.h:51
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:240
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
Class for representing a knot vector.
Definition gsKnotVector.h:80
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition gsMatrix.h:211
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
A NURBS function of one argument, with arbitrary target dimension.
Definition gsNurbs.h:40
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition gsTensorBSpline.h:45
A tensor product Non-Uniform Rational B-spline function (NURBS) of parametric dimension d,...
Definition gsTensorNurbs.h:41
Represents a B-spline curve/function with one parameter.
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of the MultiPatch class.
Represents a NURBS curve/function with one parameter.
Represents a tensor-product B-spline patch.
Represents a tensor-product NURBS patch.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266
Class gsNurbsCreator provides some simple examples of Nurbs Geometries.
Definition gsNurbsCreator.h:37
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 TensorBSpline2Ptr BSplineFatDisk(T const &r=1, T const &x=0, T const &y=0)
Inexact disk using B-splines.
Definition gsNurbsCreator.hpp:1056
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 BSplineTriangle(T const &H=1, T const &W=1)
Makes a Isosceles triangle with height H and width W.
Definition gsNurbsCreator.hpp:1636
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 BSplinePtr BSplineFatCircle(T const &r=(T)(1), T const &x=0, T const &y=0)
Inexact circle using B-splines.
Definition gsNurbsCreator.hpp:1034
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 gsMultiPatch< T > BSplineSquareGrid(int n, int m, T const &r=1, T const &lx=0, T const &ly=0)
Definition gsNurbsCreator.hpp:691
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 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 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
static TensorBSpline2Ptr BSplineLShape_p2C0()
Definition gsNurbsCreator.hpp:1287
static gsMultiPatch< T > BSplineLShapeMultiPatch_p2()
Definition gsNurbsCreator.hpp:1357
static TensorBSpline2Ptr BSplineLShape_p2C1()
Definition gsNurbsCreator.hpp:1319
static GeometryPtr BSplineQuarterAnnulus(const short_t &deg=2)
Inexact annulus using B-splines.
Definition gsNurbsCreator.hpp:888
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
static NurbsPtr NurbsCircle(T const &r=(T)(1), T const &x=0, T const &y=0)
Circle using NURBS.
Definition gsNurbsCreator.hpp:1009
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 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
static TensorBSpline2Ptr BSplineFatQuarterAnnulus(T const &r0=1, T const &r1=2)
Definition gsNurbsCreator.hpp:949
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