Code-Eli  0.3.6
piecewise_surface_test_suite.hpp
Go to the documentation of this file.
1 /*********************************************************************************
2 * Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * David D. Marshall - initial code and implementation
11 ********************************************************************************/
12 
13 #ifndef piecewise_surface_test_suite_hpp
14 #define piecewise_surface_test_suite_hpp
15 
16 #include <cmath> // std::pow, std::exp
17 
18 #include <typeinfo> // typeid
19 #include <string> // std::string
20 #include <sstream> // std::stringstream
21 #include <iomanip> // std::setw
22 #include <limits> // std::numeric_limits
23 
24 #include "eli/util/tolerance.hpp"
25 
26 #include "eli/constants/math.hpp"
29 // #include "eli/geom/surface/area.hpp"
32 
33 template<typename data__>
34 class piecewise_surface_test_suite : public Test::Suite
35 {
36  private:
44 
45  tolerance_type tol;
46 
47  protected:
48  void AddTests(const float &)
49  {
50  // add the tests
63  }
64  void AddTests(const double &)
65  {
66  // add the tests
79  }
80  void AddTests(const long double &)
81  {
82  // add the tests
95  }
96 
97  public:
99  {
100  AddTests(data__());
101  }
103  {
104  }
105 
106  private:
107  void octave_print(int figno, /*const point_type pts[][], */const piecewise_surface_type &ps) const
108  {
109  index_type i, j, pp, qq, nup, nvp;
110  data_type umin, vmin, umax, vmax;
111 
112  nup=ps.number_u_patches();
113  nvp=ps.number_v_patches();
114  ps.get_parameter_min(umin, vmin);
115  ps.get_parameter_max(umax, vmax);
116 
117  std::cout << "figure(" << figno << ");" << std::endl;
118 // std::cout << "cp_x=[" << std::endl;
119 // for (pp=0; pp<nup; ++pp)
120 // {
121 // for (qq=0; qq<nvp; ++qq)
122 // {
123 // surface_type bez;
124 // ps.get(bez, pp, qq);
125 // for (i=0; i<=bez.degree_u(); ++i)
126 // {
127 // std::cout << bez.get_control_point(i, 0).x();
128 // for (j=1; j<bez.degree_v(); ++j)
129 // {
130 // std::cout << ", " << bez.get_control_point(i, j).x();
131 // }
132 // j=bez.degree_v();
133 // std::cout << ", " << bez.get_control_point(i, j).x();
134 // if (i<bez.degree_u())
135 // std::cout << "; ";
136 // else if (pp<nup-1)
137 // std::cout << "; ";
138 // else if (qq<nvp-1)
139 // std::cout << "; ";
140 // }
141 // std::cout << std::endl;
142 // }
143 // }
144 // std::cout << "];" << std::endl;
145 //
146 // std::cout << "cp_y=[";
147 // for (pp=0; pp<nup; ++pp)
148 // {
149 // for (qq=0; qq<nvp; ++qq)
150 // {
151 // surface_type bez;
152 // ps.get(bez, pp, qq);
153 // for (i=0; i<=bez.degree_u(); ++i)
154 // {
155 // std::cout << bez.get_control_point(i, 0).y();
156 // for (j=1; j<bez.degree_v(); ++j)
157 // {
158 // std::cout << ", " << bez.get_control_point(i, j).y();
159 // }
160 // j=bez.degree_v();
161 // std::cout << ", " << bez.get_control_point(i, j).y();
162 // if (i<bez.degree_u())
163 // std::cout << "; ";
164 // else if (pp<nup-1)
165 // std::cout << "; ";
166 // else if (qq<nvp-1)
167 // std::cout << "; ";
168 // }
169 // std::cout << std::endl;
170 // }
171 // }
172 // std::cout << "];" << std::endl;
173 //
174 // std::cout << "cp_z=[";
175 // for (pp=0; pp<nup; ++pp)
176 // {
177 // for (qq=0; qq<nvp; ++qq)
178 // {
179 // surface_type bez;
180 // ps.get(bez, pp, qq);
181 // for (i=0; i<=bez.degree_u(); ++i)
182 // {
183 // std::cout << bez.get_control_point(i, 0).z();
184 // for (j=1; j<bez.degree_v(); ++j)
185 // {
186 // std::cout << ", " << bez.get_control_point(i, j).z();
187 // }
188 // j=bez.degree_v();
189 // std::cout << ", " << bez.get_control_point(i, j).z();
190 // if (i<bez.degree_u())
191 // std::cout << "; ";
192 // else if (pp<nup-1)
193 // std::cout << "; ";
194 // else if (qq<nvp-1)
195 // std::cout << "; ";
196 // }
197 // std::cout << std::endl;
198 // }
199 // }
200 // std::cout << "];" << std::endl;
201 
202  // initialize the u & v parameters
203  std::vector<data__> u(31), v(31);
204  for (i=0; i<static_cast<index_type>(u.size()); ++i)
205  {
206  u[i]=umin+(umax-umin)*static_cast<data__>(i)/(u.size()-1);
207  }
208  for (j=0; j<static_cast<index_type>(v.size()); ++j)
209  {
210  v[j]=vmin+(vmax-vmin)*static_cast<data__>(j)/(v.size()-1);
211  }
212 
213  // set the surface points
214  std::cout << "surf_x=[";
215  for (i=0; i<static_cast<index_type>(u.size()); ++i)
216  {
217  std::cout << ps.f(u[i], v[0]).x();
218  for (j=1; j<static_cast<index_type>(v.size()-1); ++j)
219  {
220  std::cout << ", " << ps.f(u[i], v[j]).x();
221  }
222  j=static_cast<index_type>(v.size()-1);
223  std::cout << ", " << ps.f(u[i], v[j]).x();
224  if (i<static_cast<index_type>(u.size()-1))
225  std::cout << "; " << std::endl;
226  }
227  std::cout << "];" << std::endl;
228 
229  std::cout << "surf_y=[";
230  for (i=0; i<static_cast<index_type>(u.size()); ++i)
231  {
232  std::cout << ps.f(u[i], v[0]).y();
233  for (j=1; j<static_cast<index_type>(v.size()-1); ++j)
234  {
235  std::cout << ", " << ps.f(u[i], v[j]).y();
236  }
237  j=static_cast<index_type>(v.size()-1);
238  std::cout << ", " << ps.f(u[i], v[j]).y();
239  if (i<static_cast<index_type>(u.size()-1))
240  std::cout << "; " << std::endl;
241  }
242  std::cout << "];" << std::endl;
243 
244  std::cout << "surf_z=[";
245  for (i=0; i<static_cast<index_type>(u.size()); ++i)
246  {
247  std::cout << ps.f(u[i], v[0]).z();
248  for (j=1; j<static_cast<index_type>(v.size()-1); ++j)
249  {
250  std::cout << ", " << ps.f(u[i], v[j]).z();
251  }
252  j=static_cast<index_type>(v.size()-1);
253  std::cout << ", " << ps.f(u[i], v[j]).z();
254  if (i<static_cast<index_type>(u.size()-1))
255  std::cout << "; " << std::endl;
256  }
257  std::cout << "];" << std::endl;
258 
259  std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
260  std::cout << "mesh(surf_x, surf_y, surf_z, zeros(size(surf_z)), 'EdgeColor', [0 0 0]);" << std::endl;
261 // std::cout << "hold on;" << std::endl;
262 // std::cout << "plot3(cp_x, cp_y, cp_z, 'ok', 'MarkerFaceColor', [0 0 0]);" << std::endl;
263 // std::cout << "hold off;" << std::endl;
264  }
265 
267  {
268  surface_type s, s1, s2, s3, s4, s5, s6, s_patches[6];
269  piecewise_surface_type ps1, ps2;
271 
272  // create 3x2 patches with unit spacing
273  ps1.init_uv(3, 2);
274  TEST_ASSERT(ps1.number_u_patches()==3);
275  TEST_ASSERT(ps1.number_v_patches()==2);
276 
277  // create and set each surface
278  index_type i, j, n(3), m(3);
279  point_type pt[3+1][3+1], pt_out;
280 
281  // create surface with specified control points
282  pt[0][0] << -15, 0, 15;
283  pt[1][0] << -5, 5, 15;
284  pt[2][0] << 5, 5, 15;
285  pt[3][0] << 15, 0, 15;
286  pt[0][1] << -15, 5, 5;
287  pt[1][1] << -5, 5, 5;
288  pt[2][1] << 5, 5, 5;
289  pt[3][1] << 15, 5, 5;
290  pt[0][2] << -15, 5, -5;
291  pt[1][2] << -5, 5, -5;
292  pt[2][2] << 5, 5, -5;
293  pt[3][2] << 15, 5, -5;
294  pt[0][3] << -15, 0, -15;
295  pt[1][3] << -5, 5, -15;
296  pt[2][3] << 5, 5, -15;
297  pt[3][3] << 15, 0, -15;
298  s.resize(n, m);
299  for (i=0; i<=n; ++i)
300  {
301  for (j=0; j<=m; ++j)
302  {
303  s.set_control_point(pt[i][j], i, j);
304  }
305  }
306 
307  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
308  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
309  err=ps1.set(s3, 0, 0); s_patches[0]=s3;
310  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
311  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
312  err=ps1.set(s5, 0, 1); s_patches[3]=s5;
313  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
314  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
315  err=ps1.set(s1, 1, 0); s_patches[1]=s1;
316  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
317  err=ps1.set(s2, 2, 0); s_patches[2]=s2;
318  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
319  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
320  err=ps1.set(s1, 1, 1); s_patches[4]=s1;
321  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
322  err=ps1.set(s2, 2, 1); s_patches[5]=s2;
323  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
324 
325  // test getting parameter max
326  data_type umax, vmax;
327  ps1.get_parameter_max(umax, vmax);
328  TEST_ASSERT(tol.approximately_equal(umax, 3));
329  TEST_ASSERT(tol.approximately_equal(vmax, 2));
330 
331  // test copy ctr
332  piecewise_surface_type ps1c(ps1);
333  TEST_ASSERT(ps1==ps1c);
334 
335  // test changing u0 and v0
336  ps1c.set_u0(-1.5);
337  TEST_ASSERT(ps1c.get_u0()==-1.5);
338  ps1c.set_v0(-1.5);
339  TEST_ASSERT(ps1c.get_v0()==-1.5);
340 
341  // test assignment operator
342  ps2=ps1;
343  TEST_ASSERT(ps2==ps1);
344  }
345 
347  {
348  surface_type s, s1, s2, s3, s4, s5, s6, s_patches[6];
349  piecewise_surface_type ps1, ps2;
351 
352  // create 3x2 patches with unit spacing
353  ps1.init_uv(3, 2);
354  TEST_ASSERT(ps1.number_u_patches()==3);
355  TEST_ASSERT(ps1.number_v_patches()==2);
356 
357  // create and set each surface
358  index_type i, j, n(3), m(3);
359  point_type pt[3+1][3+1], pt_out;
360 
361  // create surface with specified control points
362  pt[0][0] << -15, 0, 15;
363  pt[1][0] << -5, 5, 15;
364  pt[2][0] << 5, 5, 15;
365  pt[3][0] << 15, 0, 15;
366  pt[0][1] << -15, 5, 5;
367  pt[1][1] << -5, 5, 5;
368  pt[2][1] << 5, 5, 5;
369  pt[3][1] << 15, 5, 5;
370  pt[0][2] << -15, 5, -5;
371  pt[1][2] << -5, 5, -5;
372  pt[2][2] << 5, 5, -5;
373  pt[3][2] << 15, 5, -5;
374  pt[0][3] << -15, 0, -15;
375  pt[1][3] << -5, 5, -15;
376  pt[2][3] << 5, 5, -15;
377  pt[3][3] << 15, 0, -15;
378  s.resize(n, m);
379  for (i=0; i<=n; ++i)
380  {
381  for (j=0; j<=m; ++j)
382  {
383  s.set_control_point(pt[i][j], i, j);
384  }
385  }
386 
387  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
388  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
389  err=ps1.set(s3, 0, 0); s_patches[0]=s3;
390  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
391  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
392  err=ps1.set(s5, 0, 1); s_patches[3]=s5;
393  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
394  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
395  err=ps1.set(s1, 1, 0); s_patches[1]=s1;
396  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
397  err=ps1.set(s2, 2, 0); s_patches[2]=s2;
398  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
399  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
400  err=ps1.set(s1, 1, 1); s_patches[4]=s1;
401  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
402  err=ps1.set(s2, 2, 1); s_patches[5]=s2;
403  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
404 
405  // test the bounding box
407  point_type pmin_ref, pmax_ref;
408 
409  ps1.get_bounding_box(bb);
410  pmin_ref << -15, 0, -15;
411  pmax_ref << 15, 4.6875, 15;
412  TEST_ASSERT(bb.get_min()==pmin_ref);
413  TEST_ASSERT(bb.get_max()==pmax_ref);
414  }
415 
417  {
418 
419  piecewise_surface_type ps1, ps2;
420  data_type u, v, umax, vmax;
421 
422  // create 3x2 patches with unit spacing
423  ps1.init_uv(3, 2);
424 
425  // create piecewise surface
426  {
428  surface_type s, s1, s2, s3, s4, s5, s6;
429  index_type i, j, n(3), m(3);
430  point_type pt[3+1][3+1], pt_out;
431 
432  // create surface with specified control points
433  pt[0][0] << -15, 0, 15;
434  pt[1][0] << -5, 5, 15;
435  pt[2][0] << 5, 5, 15;
436  pt[3][0] << 15, 0, 15;
437  pt[0][1] << -15, 5, 5;
438  pt[1][1] << -5, 5, 5;
439  pt[2][1] << 5, 5, 5;
440  pt[3][1] << 15, 5, 5;
441  pt[0][2] << -15, 5, -5;
442  pt[1][2] << -5, 5, -5;
443  pt[2][2] << 5, 5, -5;
444  pt[3][2] << 15, 5, -5;
445  pt[0][3] << -15, 0, -15;
446  pt[1][3] << -5, 5, -15;
447  pt[2][3] << 5, 5, -15;
448  pt[3][3] << 15, 0, -15;
449  s.resize(n, m);
450  for (i=0; i<=n; ++i)
451  {
452  for (j=0; j<=m; ++j)
453  {
454  s.set_control_point(pt[i][j], i, j);
455  }
456  }
457 
458  // create and set each surface
459  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
460  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
461  err=ps1.set(s3, 0, 0);
462  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
463  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
464  err=ps1.set(s5, 0, 1);
465  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
466  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
467  err=ps1.set(s1, 1, 0);
468  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
469  err=ps1.set(s2, 2, 0);
470  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
471  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
472  err=ps1.set(s1, 1, 1);
473  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
474  err=ps1.set(s2, 2, 1);
475  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
476  }
477  ps1.get_parameter_max(umax, vmax);
478 
479  // reverse u-direction
480  ps2=ps1;
481  ps2.reverse_u();
482 
483  // test point
484  u=1.25;
485  v=0.75;
486  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(umax-u, v)));
487  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), -ps2.f_u(umax-u, v)));
488  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(umax-u, v)));
489 
490  // test another point
491  u=2.75;
492  v=1.25;
493  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(umax-u, v)));
494  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), -ps2.f_u(umax-u, v)));
495  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(umax-u, v)));
496 
497  // reverse v-direction
498  ps2=ps1;
499  ps2.reverse_v();
500 
501  // test point
502  u=1.25;
503  v=0.75;
504  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, vmax-v)));
505  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, vmax-v)));
506  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), -ps2.f_v(u, vmax-v)));
507 
508  // test another point
509  u=2.75;
510  v=1.25;
511  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, vmax-v)));
512  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, vmax-v)));
513  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), -ps2.f_v(u, vmax-v)));
514  }
515 
516  void swap_test()
517  {
518  piecewise_surface_type ps1, ps2;
519  data_type u, v;
520 
521  // create 3x2 patches with unit spacing
522  ps1.init_uv(3, 2);
523  TEST_ASSERT(ps1.number_u_patches()==3);
524  TEST_ASSERT(ps1.number_v_patches()==2);
525 
526  // create piecewise surface
527  {
529  surface_type s, s1, s2, s3, s4, s5, s6;
530  index_type i, j, n(3), m(3);
531  point_type pt[3+1][3+1], pt_out;
532 
533  // create surface with specified control points
534  pt[0][0] << -15, 0, 15;
535  pt[1][0] << -5, 5, 15;
536  pt[2][0] << 5, 5, 15;
537  pt[3][0] << 15, 0, 15;
538  pt[0][1] << -15, 5, 5;
539  pt[1][1] << -5, 5, 5;
540  pt[2][1] << 5, 5, 5;
541  pt[3][1] << 15, 5, 5;
542  pt[0][2] << -15, 5, -5;
543  pt[1][2] << -5, 5, -5;
544  pt[2][2] << 5, 5, -5;
545  pt[3][2] << 15, 5, -5;
546  pt[0][3] << -15, 0, -15;
547  pt[1][3] << -5, 5, -15;
548  pt[2][3] << 5, 5, -15;
549  pt[3][3] << 15, 0, -15;
550  s.resize(n, m);
551  for (i=0; i<=n; ++i)
552  {
553  for (j=0; j<=m; ++j)
554  {
555  s.set_control_point(pt[i][j], i, j);
556  }
557  }
558 
559  // create and set each surface
560  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
561  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
562  err=ps1.set(s3, 0, 0);
563  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
564  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
565  err=ps1.set(s5, 0, 1);
566  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
567  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
568  err=ps1.set(s1, 1, 0);
569  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
570  err=ps1.set(s2, 2, 0);
571  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
572  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
573  err=ps1.set(s1, 1, 1);
574  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
575  err=ps1.set(s2, 2, 1);
576  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
577  }
578 
579  // create second piecewise surface and swap coordinate directions
580  ps2=ps1;
581  ps2.swap_uv();
582 
583  TEST_ASSERT(ps2.number_u_patches()==2);
584  TEST_ASSERT(ps2.number_v_patches()==3);
585 
586  // test point
587  u=1.25;
588  v=0.75;
589  TEST_ASSERT(ps1.f(u, v)==ps2.f(v, u));
590  TEST_ASSERT(ps1.f_u(u, v)==ps2.f_v(v, u));
591  TEST_ASSERT(ps1.f_v(u, v)==ps2.f_u(v, u));
592 
593  // test another point
594  u=2.75;
595  v=1.25;
596  TEST_ASSERT(ps1.f(u, v)==ps2.f(v, u));
597  TEST_ASSERT(ps1.f_u(u, v)==ps2.f_v(v, u));
598  TEST_ASSERT(ps1.f_v(u, v)==ps2.f_u(v, u));
599  }
600 
602  {
604  piecewise_surface_type ps1, ps2;
605  data_type u, v;
606 
607  // create 3x2 patches with unit spacing
608  ps1.init_uv(3, 2);
609 
610  // create piecewise surface
611  {
612  surface_type s, s1, s2, s3, s4, s5, s6;
613  index_type i, j, n(3), m(3);
614  point_type pt[3+1][3+1], pt_out;
615 
616  // create surface with specified control points
617  pt[0][0] << -15, 0, 15;
618  pt[1][0] << -5, 5, 15;
619  pt[2][0] << 5, 5, 15;
620  pt[3][0] << 15, 0, 15;
621  pt[0][1] << -15, 5, 5;
622  pt[1][1] << -5, 5, 5;
623  pt[2][1] << 5, 5, 5;
624  pt[3][1] << 15, 5, 5;
625  pt[0][2] << -15, 5, -5;
626  pt[1][2] << -5, 5, -5;
627  pt[2][2] << 5, 5, -5;
628  pt[3][2] << 15, 5, -5;
629  pt[0][3] << -15, 0, -15;
630  pt[1][3] << -5, 5, -15;
631  pt[2][3] << 5, 5, -15;
632  pt[3][3] << 15, 0, -15;
633  s.resize(n, m);
634  for (i=0; i<=n; ++i)
635  {
636  for (j=0; j<=m; ++j)
637  {
638  s.set_control_point(pt[i][j], i, j);
639  }
640  }
641 
642  // create and set each surface
643  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
644  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
645  err=ps1.set(s3, 0, 0);
646  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
647  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
648  err=ps1.set(s5, 0, 1);
649  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
650  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
651  err=ps1.set(s1, 1, 0);
652  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
653  err=ps1.set(s2, 2, 0);
654  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
655  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
656  err=ps1.set(s1, 1, 1);
657  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
658  err=ps1.set(s2, 2, 1);
659  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
660  }
661 
662  surface_type s;
663 
664  // test adding valid patch
665  ps2=ps1;
666  ps2.get(s, 2, 1);
667  s.promote_u();
668  s.promote_v();
669  err=ps2.replace(s, 2, 1);
670  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
671 
672  u=2.25;
673  v=1.75;
674  TEST_ASSERT(ps1.f(u, v)==ps2.f(u, v));
675  TEST_ASSERT(ps1.f_u(u, v)==ps2.f_u(u, v));
676  TEST_ASSERT(ps1.f_v(u, v)==ps2.f_v(u, v));
677 
678  // test adding invalid patch
679  point_type nudge;
680  nudge << 0, static_cast<data_type>(0.01), 0;
681  ps2=ps1;
682  ps2.get(s, 2, 1);
683  s.set_control_point(s.get_control_point(0, 0)+nudge, 0, 0);
684  err=ps2.replace(s, 2, 1);
686  }
687 
689  {
690  piecewise_surface_type ps1, ps2;
691  data_type u, v;
693 
694  // create 3x2 patches with unit spacing
695  ps1.init_uv(3, 2);
696 
697  // create piecewise surface
698  {
699  surface_type s, s1, s2, s3, s4, s5, s6;
700  index_type i, j, n(3), m(3);
701  point_type pt[3+1][3+1], pt_out;
702 
703  // create surface with specified control points
704  pt[0][0] << -15, 0, 15;
705  pt[1][0] << -5, 5, 15;
706  pt[2][0] << 5, 5, 15;
707  pt[3][0] << 15, 0, 15;
708  pt[0][1] << -15, 5, 5;
709  pt[1][1] << -5, 5, 5;
710  pt[2][1] << 5, 5, 5;
711  pt[3][1] << 15, 5, 5;
712  pt[0][2] << -15, 5, -5;
713  pt[1][2] << -5, 5, -5;
714  pt[2][2] << 5, 5, -5;
715  pt[3][2] << 15, 5, -5;
716  pt[0][3] << -15, 0, -15;
717  pt[1][3] << -5, 5, -15;
718  pt[2][3] << 5, 5, -15;
719  pt[3][3] << 15, 0, -15;
720  s.resize(n, m);
721  for (i=0; i<=n; ++i)
722  {
723  for (j=0; j<=m; ++j)
724  {
725  s.set_control_point(pt[i][j], i, j);
726  }
727  }
728 
729  // create and set each surface
730  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
731  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
732  err=ps1.set(s3, 0, 0);
733  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
734  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
735  err=ps1.set(s5, 0, 1);
736  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
737  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
738  err=ps1.set(s1, 1, 0);
739  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
740  err=ps1.set(s2, 2, 0);
741  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
742  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
743  err=ps1.set(s1, 1, 1);
744  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
745  err=ps1.set(s2, 2, 1);
746  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
747  }
748 
749  // test translation
750  {
751  point_type trans;
752 
753  // set up translation vector and apply
754  u=1.5;
755  v=0.75;
756  ps2=ps1;
757  trans << 2, 1, 3;
758  ps2.translate(trans);
759  TEST_ASSERT(tol.approximately_equal(ps2.f(u, v), ps1.f(u, v)+trans));
760  }
761 
762  // test rotation about origin
763  {
765 
766  // set up rotation and apply
767  data_type one(1);
768  ps2=ps1;
769  rmat << std::cos(one), 0, -std::sin(one),
770  0, one, 0,
771  std::sin(one), 0, std::cos(one);
772  ps2.rotate(rmat);
773  TEST_ASSERT(tol.approximately_equal(ps2.f(u, v), ps1.f(u, v)*rmat.transpose()));
774  }
775 
776  // test rotation about point
777  {
779  point_type rorig;
780 
781  // set up rotation and apply
782  data_type one(1);
783  ps2=ps1;
784  rorig << 2, 1, 3;
785  rmat << std::cos(one), 0, -std::sin(one),
786  0, one, 0,
787  std::sin(one), 0, std::cos(one);
788  ps2.rotate(rmat, rorig);
789  TEST_ASSERT(tol.approximately_equal(ps2.f(u, v), rorig+(ps1.f(u, v)-rorig)*rmat.transpose()));
790  }
791  }
792 
794  {
795  surface_type s_patches[6];
796  piecewise_surface_type ps1;
797  data_type u, v, up, vp;
799 
800  // create 3x2 patches with unit spacing
801  ps1.init_uv(3, 2);
802 
803  // create piecewise surface
804  {
805  surface_type s, s1, s2, s3, s4, s5, s6;
806  index_type i, j, n(3), m(3);
807  point_type pt[3+1][3+1], pt_out;
808 
809  // create surface with specified control points
810  pt[0][0] << -15, 0, 15;
811  pt[1][0] << -5, 5, 15;
812  pt[2][0] << 5, 5, 15;
813  pt[3][0] << 15, 0, 15;
814  pt[0][1] << -15, 5, 5;
815  pt[1][1] << -5, 5, 5;
816  pt[2][1] << 5, 5, 5;
817  pt[3][1] << 15, 5, 5;
818  pt[0][2] << -15, 5, -5;
819  pt[1][2] << -5, 5, -5;
820  pt[2][2] << 5, 5, -5;
821  pt[3][2] << 15, 5, -5;
822  pt[0][3] << -15, 0, -15;
823  pt[1][3] << -5, 5, -15;
824  pt[2][3] << 5, 5, -15;
825  pt[3][3] << 15, 0, -15;
826  s.resize(n, m);
827  for (i=0; i<=n; ++i)
828  {
829  for (j=0; j<=m; ++j)
830  {
831  s.set_control_point(pt[i][j], i, j);
832  }
833  }
834 
835  // create and set each surface
836  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
837  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
838  err=ps1.set(s3, 0, 0); s_patches[0]=s3;
839  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
840  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
841  err=ps1.set(s5, 0, 1); s_patches[3]=s5;
842  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
843  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
844  err=ps1.set(s1, 1, 0); s_patches[1]=s1;
845  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
846  err=ps1.set(s2, 2, 0); s_patches[2]=s2;
847  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
848  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
849  err=ps1.set(s1, 1, 1); s_patches[4]=s1;
850  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
851  err=ps1.set(s2, 2, 1); s_patches[5]=s2;
852  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
853  }
854 
855  // test evaluation on first patch
856  u=0.25;
857  v=0.75;
858  up=u;
859  vp=v;
860  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), s_patches[0].f(up, vp)));
861  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), s_patches[0].f_u(up, vp)));
862  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), s_patches[0].f_v(up, vp)));
863  TEST_ASSERT(tol.approximately_equal(ps1.f_uu(u, v), s_patches[0].f_uu(up, vp)));
864  TEST_ASSERT(tol.approximately_equal(ps1.f_uv(u, v), s_patches[0].f_uv(up, vp)));
865  TEST_ASSERT(tol.approximately_equal(ps1.f_vv(u, v), s_patches[0].f_vv(up, vp)));
866 
867  // test evaluation on a lower patch
868  u=2.25;
869  v=0.75;
870  up=u-2;
871  vp=v;
872  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), s_patches[2].f(up, vp)));
873  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), s_patches[2].f_u(up, vp)));
874  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), s_patches[2].f_v(up, vp)));
875  TEST_ASSERT(tol.approximately_equal(ps1.f_uu(u, v), s_patches[2].f_uu(up, vp)));
876  TEST_ASSERT(tol.approximately_equal(ps1.f_uv(u, v), s_patches[2].f_uv(up, vp)));
877  TEST_ASSERT(tol.approximately_equal(ps1.f_vv(u, v), s_patches[2].f_vv(up, vp)));
878 
879  // test evaluation on an upper patch
880  u=2.25;
881  v=1.75;
882  up=u-2;
883  vp=v-1;
884  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), s_patches[5].f(up, vp)));
885  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), s_patches[5].f_u(up, vp)));
886  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), s_patches[5].f_v(up, vp)));
887  TEST_ASSERT(tol.approximately_equal(ps1.f_uu(u, v), s_patches[5].f_uu(up, vp)));
888  TEST_ASSERT(tol.approximately_equal(ps1.f_uv(u, v), s_patches[5].f_uv(up, vp)));
889  TEST_ASSERT(tol.approximately_equal(ps1.f_vv(u, v), s_patches[5].f_vv(up, vp)));
890  }
891 
892  void split_test()
893  {
894  piecewise_surface_type ps1, ps2;
895  data_type u, v;
896 
897  // create 3x2 patches with unit spacing
898  ps1.init_uv(3, 2);
899 
900  // create piecewise surface
901  {
903  surface_type s, s1, s2, s3, s4, s5, s6;
904  index_type i, j, n(3), m(3);
905  point_type pt[3+1][3+1], pt_out;
906 
907  // create surface with specified control points
908  pt[0][0] << -15, 0, 15;
909  pt[1][0] << -5, 5, 15;
910  pt[2][0] << 5, 5, 15;
911  pt[3][0] << 15, 0, 15;
912  pt[0][1] << -15, 5, 5;
913  pt[1][1] << -5, 5, 5;
914  pt[2][1] << 5, 5, 5;
915  pt[3][1] << 15, 5, 5;
916  pt[0][2] << -15, 5, -5;
917  pt[1][2] << -5, 5, -5;
918  pt[2][2] << 5, 5, -5;
919  pt[3][2] << 15, 5, -5;
920  pt[0][3] << -15, 0, -15;
921  pt[1][3] << -5, 5, -15;
922  pt[2][3] << 5, 5, -15;
923  pt[3][3] << 15, 0, -15;
924  s.resize(n, m);
925  for (i=0; i<=n; ++i)
926  {
927  for (j=0; j<=m; ++j)
928  {
929  s.set_control_point(pt[i][j], i, j);
930  }
931  }
932 
933  // create and set each surface
934  s.split_v(s1, s2, 0.5); // this splits surface into lower and upper
935  s1.split_u(s3, s4, 0.5); // this splits lower into first segment and last two
936  err=ps1.set(s3, 0, 0);
937  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
938  s2.split_u(s5, s6, 0.5); // this splits upper into first segment and last two
939  err=ps1.set(s5, 0, 1);
940  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
941  s4.split_u(s1, s2, 0.5); // this splits lower end into final two pieces
942  err=ps1.set(s1, 1, 0);
943  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
944  err=ps1.set(s2, 2, 0);
945  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
946  s6.split_u(s1, s2, 0.5); // this splits the upper end into final two pieces
947  err=ps1.set(s1, 1, 1);
948  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
949  err=ps1.set(s2, 2, 1);
950  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
951  }
952 
953  // split u-direction
954  ps2=ps1;
955  ps2.split_u(1.5);
956 
957  // test evaluation before split
958  u=0.25;
959  v=1.5;
960  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
961  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
962  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
963 
964  // test evaluation before split
965  u=1.25;
966  v=1.75;
967  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
968  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
969  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
970 
971  // test evaluation after split
972  u=1.75;
973  v=0.75;
974  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
975  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
976  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
977 
978  // test evaluation after split
979  u=2.25;
980  v=0.25;
981  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
982  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
983  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
984 
985  // split v-direction
986  ps2=ps1;
987  ps2.split_v(1.5);
988 
989  // test evaluation before split
990  u=0.25;
991  v=0.5;
992  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
993  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
994  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
995 
996  // test evaluation before split
997  u=1.25;
998  v=0.75;
999  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
1000  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
1001  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
1002 
1003  // test evaluation after split
1004  u=1.75;
1005  v=1.75;
1006  TEST_ASSERT(tol.approximately_equal(ps1.f(u, v), ps2.f(u, v)));
1007  TEST_ASSERT(tol.approximately_equal(ps1.f_u(u, v), ps2.f_u(u, v)));
1008  TEST_ASSERT(tol.approximately_equal(ps1.f_v(u, v), ps2.f_v(u, v)));
1009  }
1010 
1012  {
1013  piecewise_surface_type ps1, ps2;
1014  data_type u, v;
1015 
1016  // create 3x2 patches with unit spacing
1017  ps1.init_uv(1,1);
1018 
1019  // create piecewise surface
1020  {
1022  surface_type s;
1023  index_type i, j, n(5), m(4);
1024  point_type pt[5+1][4+1], pt_out;
1025 
1026  // create surface with specified control points
1027  pt[0][0] << 0, 0, 15;
1028  pt[1][0] << 2, 6, 15;
1029  pt[2][0] << 3, 0, 15;
1030  pt[3][0] << 5, 4, 15;
1031  pt[4][0] << 7, 1, 15;
1032  pt[5][0] << 9, 1, 15;
1033  pt[0][1] << 0, 0, 11;
1034  pt[1][1] << 2, 6, 11;
1035  pt[2][1] << 3, 0, 11;
1036  pt[3][1] << 5, 4, 11;
1037  pt[4][1] << 7, 1, 11;
1038  pt[5][1] << 9, 1, 11;
1039  pt[0][2] << 0, 0, 3;
1040  pt[1][2] << 2, 6, 3;
1041  pt[2][2] << 3, 0, 3;
1042  pt[3][2] << 5, 4, 3;
1043  pt[4][2] << 7, 1, 3;
1044  pt[5][2] << 9, 1, 3;
1045  pt[0][3] << 0, 0, 0;
1046  pt[1][3] << 2, 6, 0;
1047  pt[2][3] << 3, 0, 0;
1048  pt[3][3] << 5, 4, 0;
1049  pt[4][3] << 7, 1, 0;
1050  pt[5][3] << 9, 1, 0;
1051  pt[0][4] << 0, 0, -5;
1052  pt[1][4] << 2, 6, -5;
1053  pt[2][4] << 3, 0, -5;
1054  pt[3][4] << 5, 4, -5;
1055  pt[4][4] << 7, 1, -5;
1056  pt[5][4] << 9, 1, -5;
1057 
1058  s.resize(n, m);
1059  for (i=0; i<=n; ++i)
1060  {
1061  for (j=0; j<=m; ++j)
1062  {
1063  s.set_control_point(pt[i][j], i, j);
1064  }
1065  }
1066 
1067  err=ps1.set(s, 0, 0);
1068  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1069 
1070  }
1071 
1072  data_type ttol = static_cast<data_type>(1e-3);
1073 
1074  // to_cubic u-direction
1075  ps2=ps1;
1076 
1077  ps2.to_cubic_u(ttol);
1078 
1079  index_type mind, maxd;
1080 
1081  ps2.degree_u(mind, maxd);
1082 
1083  TEST_ASSERT(mind==3);
1084  TEST_ASSERT(maxd==3);
1085 
1086  // printf("nu: %d nv: %d\n", ps2.number_u_patches(), ps2.number_v_patches());
1087 
1088  u=0.25;
1089  v=0.5;
1090  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1091 
1092  u=0.25;
1093  v=0.75;
1094  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1095 
1096  u=0.75;
1097  v=0.75;
1098  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1099 
1100  u=0.25;
1101  v=0.25;
1102  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1103 
1104  // to_cubic v-direction
1105  ps2=ps1;
1106 
1107  ps2.to_cubic_v(ttol);
1108 
1109  ps2.degree_v(mind, maxd);
1110 
1111  TEST_ASSERT(mind==3);
1112  TEST_ASSERT(maxd==3);
1113 
1114  // printf("nu: %d nv: %d\n", ps2.number_u_patches(), ps2.number_v_patches());
1115 
1116  u=0.25;
1117  v=0.5;
1118  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1119 
1120  u=0.25;
1121  v=0.75;
1122  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1123 
1124  u=0.75;
1125  v=0.75;
1126  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1127 
1128  // to_cubic u and v-direction
1129  ps2=ps1;
1130 
1131  ps2.to_cubic(ttol);
1132 
1133  ps2.degree_u(mind, maxd);
1134 
1135  TEST_ASSERT(mind==3);
1136  TEST_ASSERT(maxd==3);
1137 
1138  ps2.degree_v(mind, maxd);
1139 
1140  TEST_ASSERT(mind==3);
1141  TEST_ASSERT(maxd==3);
1142 
1143  // printf("nu: %d nv: %d\n", ps2.number_u_patches(), ps2.number_v_patches());
1144 
1145  u=0.25;
1146  v=0.5;
1147  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1148 
1149  u=0.25;
1150  v=0.75;
1151  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1152 
1153  u=0.75;
1154  v=0.75;
1155  TEST_ASSERT((ps1.f(u, v)-ps2.f(u, v)).norm() < ttol);
1156  }
1157 
1158  void area_test()
1159  {
1160 #if 0
1161  data_type eps(std::numeric_limits<data__>::epsilon());
1162  piecewise_surface_type c1;
1163  curve_type bc[3];
1164  data_type dt[3], len, bc_len[3], ref_len, t0, t1, temp0, temp1;
1165  typename curve_type::control_point_type cntrl1_in[4], cntrl2_in[5], cntrl3_in[3];
1167  data_type tol(std::sqrt(eps));
1168 
1169  // create piecewise curve
1170  cntrl1_in[0] << 2.0, 2.0, 0.0;
1171  cntrl1_in[1] << 1.0, 1.5, 0.0;
1172  cntrl1_in[2] << 3.5, 0.0, 0.0;
1173  cntrl1_in[3] << 4.0, 1.0, 0.0;
1174  dt[0]=0.5;
1175  bc[0].resize(3);
1176  for (index_type i=0; i<4; ++i)
1177  {
1178  bc[0].set_control_point(cntrl1_in[i], i);
1179  }
1180  eli::geom::curve::length(bc_len[0], bc[0], tol);
1181  cntrl2_in[0] << 4.0, 1.0, 0.0;
1182  cntrl2_in[1] << 5.0, 2.5, 0.0;
1183  cntrl2_in[2] << 5.5, 1.0, 0.0;
1184  cntrl2_in[3] << 6.0, 0.0, 0.0;
1185  cntrl2_in[4] << 6.5,-0.5, 0.0;
1186  dt[1]=2.0;
1187  bc[1].resize(4);
1188  for (index_type i=0; i<5; ++i)
1189  {
1190  bc[1].set_control_point(cntrl2_in[i], i);
1191  }
1192  eli::geom::curve::length(bc_len[1], bc[1], tol);
1193  cntrl3_in[0] << 6.5,-0.5, 0.0;
1194  cntrl3_in[1] << 6.0,-1.0, 0.0;
1195  cntrl3_in[2] << 5.5,-2.0, 0.0;
1196  dt[2]=1.5;
1197  bc[2].resize(2);
1198  for (index_type i=0; i<3; ++i)
1199  {
1200  bc[2].set_control_point(cntrl3_in[i], i);
1201  }
1202  eli::geom::curve::length(bc_len[2], bc[2], tol);
1203  err=c1.set(bc, bc+3, dt);
1204  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1205  TEST_ASSERT(c1.number_segments()==3);
1206 
1207  // create two segment curve calc length of each segment to compare
1208  eli::geom::curve::length(len, c1, tol);
1209  ref_len=bc_len[0]+bc_len[1]+bc_len[2];
1210  TEST_ASSERT(len==ref_len);
1211 
1212  // choose part of first segment to calc length and compare
1213  t0=0.125;
1214  t1=0.375;
1215  eli::geom::curve::length(len, c1, t0, t1, tol);
1216  eli::geom::curve::length(ref_len, bc[0], 0.25, 0.75, tol);
1217  TEST_ASSERT(len==ref_len);
1218 
1219  // choose part of second segment to calc length and compare
1220  t0=0.25;
1221  t1=1.5;
1222  eli::geom::curve::length(len, c1, t0, t1, tol);
1223  eli::geom::curve::length(temp0, bc[0], 0.5, 1, tol);
1224  eli::geom::curve::length(temp1, bc[1], 0, 0.5, tol);
1225  ref_len=temp0+temp1;
1226  TEST_ASSERT(std::abs(len-ref_len)<2*tol);
1227 
1228  // choose part of third segment to calc length and compare
1229  t0=0.25;
1230  t1=3.25;
1231  eli::geom::curve::length(len, c1, t0, t1, tol);
1232  eli::geom::curve::length(temp0, bc[0], 0.5, 1, tol);
1233  eli::geom::curve::length(temp1, bc[2], 0, 0.5, tol);
1234  ref_len=temp0+bc_len[1]+temp1;
1235  TEST_ASSERT(std::abs(len-ref_len)<166*tol);
1236 #endif
1237  }
1238 
1240  {
1241  const index_type n(3), m(3);
1242  surface_type s(n, m);
1243  point_type cp[3+1][3+1], pt_out, pt_ref;
1244  point_type pt, norm, u_contra, v_contra;
1245  data_type u, v, d;
1246  index_type i, j;
1247  piecewise_surface_type pws;
1248  piecewise_curve_type pwc;
1250 
1251  pws.init_uv(1, 1);
1252 
1253  // create surface with specified control points
1254  cp[0][0] << -15, 0, 15;
1255  cp[1][0] << -5, 5, 15;
1256  cp[2][0] << 5, 5, 15;
1257  cp[3][0] << 15, 0, 15;
1258  cp[0][1] << -15, 5, 5;
1259  cp[1][1] << -5, 5, 5;
1260  cp[2][1] << 5, 5, 5;
1261  cp[3][1] << 15, 5, 5;
1262  cp[0][2] << -15, 5, -5;
1263  cp[1][2] << -5, 5, -5;
1264  cp[2][2] << 5, 5, -5;
1265  cp[3][2] << 15, 5, -5;
1266  cp[0][3] << -15, 0, -15;
1267  cp[1][3] << -5, 5, -15;
1268  cp[2][3] << 5, 5, -15;
1269  cp[3][3] << 15, 0, -15;
1270 
1271  // create surface with specified dimensions and set control points
1272  for (i=0; i<=n; ++i)
1273  {
1274  for (j=0; j<=m; ++j)
1275  {
1276  s.set_control_point(cp[i][j], i, j);
1277  }
1278  }
1279  TEST_ASSERT(s.open_u());
1280  TEST_ASSERT(s.open_v());
1281 
1282  err=pws.set(s, 0, 0);
1283  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1284 
1285  pws.split_u(static_cast<data_type>(0.2));
1286  pws.split_u(static_cast<data_type>(0.3));
1287  pws.split_u(static_cast<data_type>(0.6));
1288  pws.split_u(static_cast<data_type>(0.7));
1289 
1290  pws.split_v(static_cast<data_type>(0.2));
1291  pws.split_v(static_cast<data_type>(0.412));
1292  pws.split_v(static_cast<data_type>(0.6));
1293  pws.split_v(static_cast<data_type>(0.895));
1294 
1295  // Extract u curve
1296  u=0;
1297  pws.get_uconst_curve(pwc, u);
1298 
1299  v=0;
1300  pt_ref=pws.f(u, v);
1301  pt_out=pwc.f(v);
1302  TEST_ASSERT(pt_out==pt_ref);
1303 
1304  v=static_cast<data_type>(0.1);
1305  pt_ref=pws.f(u, v);
1306  pt_out=pwc.f(v);
1307  TEST_ASSERT(pt_out==pt_ref);
1308 
1309  v=static_cast<data_type>(0.2);
1310  pt_ref=pws.f(u, v);
1311  pt_out=pwc.f(v);
1312  TEST_ASSERT(pt_out==pt_ref);
1313 
1314  v=static_cast<data_type>(0.4);
1315  pt_ref=pws.f(u, v);
1316  pt_out=pwc.f(v);
1317  TEST_ASSERT(pt_out==pt_ref);
1318 
1319  v=static_cast<data_type>(0.6);
1320  pt_ref=pws.f(u, v);
1321  pt_out=pwc.f(v);
1322  TEST_ASSERT(pt_out==pt_ref);
1323 
1324  v=static_cast<data_type>(0.8);
1325  pt_ref=pws.f(u, v);
1326  pt_out=pwc.f(v);
1327  TEST_ASSERT(pt_out==pt_ref);
1328 
1329  v=1;
1330  pt_ref=pws.f(u, v);
1331  pt_out=pwc.f(v);
1332  TEST_ASSERT(pt_out==pt_ref);
1333 
1334  // Extract u curve
1335  u=static_cast<data_type>(0.1);
1336  pws.get_uconst_curve(pwc, u);
1337 
1338  v=0;
1339  pt_ref=pws.f(u, v);
1340  pt_out=pwc.f(v);
1341  TEST_ASSERT(pt_out==pt_ref);
1342 
1343  v=static_cast<data_type>(0.1);
1344  pt_ref=pws.f(u, v);
1345  pt_out=pwc.f(v);
1346  TEST_ASSERT(pt_out==pt_ref);
1347 
1348  v=static_cast<data_type>(0.2);
1349  pt_ref=pws.f(u, v);
1350  pt_out=pwc.f(v);
1351  TEST_ASSERT(pt_out==pt_ref);
1352 
1353  v=static_cast<data_type>(0.4);
1354  pt_ref=pws.f(u, v);
1355  pt_out=pwc.f(v);
1356  TEST_ASSERT(pt_out==pt_ref);
1357 
1358  v=static_cast<data_type>(0.6);
1359  pt_ref=pws.f(u, v);
1360  pt_out=pwc.f(v);
1361  TEST_ASSERT(pt_out==pt_ref);
1362 
1363  v=static_cast<data_type>(0.8);
1364  pt_ref=pws.f(u, v);
1365  pt_out=pwc.f(v);
1366  TEST_ASSERT(pt_out==pt_ref);
1367 
1368  v=1;
1369  pt_ref=pws.f(u, v);
1370  pt_out=pwc.f(v);
1371  TEST_ASSERT(pt_out==pt_ref);
1372 
1373  // Extract u curve
1374  u=static_cast<data_type>(0.2);
1375  pws.get_uconst_curve(pwc, u);
1376 
1377  v=0;
1378  pt_ref=pws.f(u, v);
1379  pt_out=pwc.f(v);
1380  TEST_ASSERT(pt_out==pt_ref);
1381 
1382  v=static_cast<data_type>(0.1);
1383  pt_ref=pws.f(u, v);
1384  pt_out=pwc.f(v);
1385  TEST_ASSERT(pt_out==pt_ref);
1386 
1387  v=static_cast<data_type>(0.2);
1388  pt_ref=pws.f(u, v);
1389  pt_out=pwc.f(v);
1390  TEST_ASSERT(pt_out==pt_ref);
1391 
1392  v=static_cast<data_type>(0.4);
1393  pt_ref=pws.f(u, v);
1394  pt_out=pwc.f(v);
1395  TEST_ASSERT(pt_out==pt_ref);
1396 
1397  v=static_cast<data_type>(0.6);
1398  pt_ref=pws.f(u, v);
1399  pt_out=pwc.f(v);
1400  TEST_ASSERT(pt_out==pt_ref);
1401 
1402  v=static_cast<data_type>(0.8);
1403  pt_ref=pws.f(u, v);
1404  pt_out=pwc.f(v);
1405  TEST_ASSERT(pt_out==pt_ref);
1406 
1407  v=1;
1408  pt_ref=pws.f(u, v);
1409  pt_out=pwc.f(v);
1410  TEST_ASSERT(pt_out==pt_ref);
1411 
1412  // Extract u curve
1413  u=static_cast<data_type>(0.5);
1414  pws.get_uconst_curve(pwc, u);
1415 
1416  v=0;
1417  pt_ref=pws.f(u, v);
1418  pt_out=pwc.f(v);
1419  TEST_ASSERT(pt_out==pt_ref);
1420 
1421  v=static_cast<data_type>(0.1);
1422  pt_ref=pws.f(u, v);
1423  pt_out=pwc.f(v);
1424  TEST_ASSERT(pt_out==pt_ref);
1425 
1426  v=static_cast<data_type>(0.2);
1427  pt_ref=pws.f(u, v);
1428  pt_out=pwc.f(v);
1429  TEST_ASSERT(pt_out==pt_ref);
1430 
1431  v=static_cast<data_type>(0.4);
1432  pt_ref=pws.f(u, v);
1433  pt_out=pwc.f(v);
1434  TEST_ASSERT(pt_out==pt_ref);
1435 
1436  v=static_cast<data_type>(0.6);
1437  pt_ref=pws.f(u, v);
1438  pt_out=pwc.f(v);
1439  TEST_ASSERT(pt_out==pt_ref);
1440 
1441  v=static_cast<data_type>(0.8);
1442  pt_ref=pws.f(u, v);
1443  pt_out=pwc.f(v);
1444  TEST_ASSERT(pt_out==pt_ref);
1445 
1446  v=1;
1447  pt_ref=pws.f(u, v);
1448  pt_out=pwc.f(v);
1449  TEST_ASSERT(pt_out==pt_ref);
1450 
1451  // Extract u curve
1452  u=1;
1453  pws.get_uconst_curve(pwc, u);
1454 
1455  v=0;
1456  pt_ref=pws.f(u, v);
1457  pt_out=pwc.f(v);
1458  TEST_ASSERT(pt_out==pt_ref);
1459 
1460  v=static_cast<data_type>(0.1);
1461  pt_ref=pws.f(u, v);
1462  pt_out=pwc.f(v);
1463  TEST_ASSERT(pt_out==pt_ref);
1464 
1465  v=static_cast<data_type>(0.2);
1466  pt_ref=pws.f(u, v);
1467  pt_out=pwc.f(v);
1468  TEST_ASSERT(pt_out==pt_ref);
1469 
1470  v=static_cast<data_type>(0.4);
1471  pt_ref=pws.f(u, v);
1472  pt_out=pwc.f(v);
1473  TEST_ASSERT(pt_out==pt_ref);
1474 
1475  v=static_cast<data_type>(0.6);
1476  pt_ref=pws.f(u, v);
1477  pt_out=pwc.f(v);
1478  TEST_ASSERT(pt_out==pt_ref);
1479 
1480  v=static_cast<data_type>(0.8);
1481  pt_ref=pws.f(u, v);
1482  pt_out=pwc.f(v);
1483  TEST_ASSERT(pt_out==pt_ref);
1484 
1485  v=1;
1486  pt_ref=pws.f(u, v);
1487  pt_out=pwc.f(v);
1488  TEST_ASSERT(pt_out==pt_ref);
1489 
1490 
1491 
1492  // Extract v curve
1493  v=0;
1494  pws.get_vconst_curve(pwc, v);
1495 
1496  u=0;
1497  pt_ref=pws.f(u, v);
1498  pt_out=pwc.f(u);
1499  TEST_ASSERT(pt_out==pt_ref);
1500 
1501  u=static_cast<data_type>(0.1);
1502  pt_ref=pws.f(u, v);
1503  pt_out=pwc.f(u);
1504  TEST_ASSERT(pt_out==pt_ref);
1505 
1506  u=static_cast<data_type>(0.2);
1507  pt_ref=pws.f(u, v);
1508  pt_out=pwc.f(u);
1509  TEST_ASSERT(pt_out==pt_ref);
1510 
1511  u=static_cast<data_type>(0.4);
1512  pt_ref=pws.f(u, v);
1513  pt_out=pwc.f(u);
1514  TEST_ASSERT(pt_out==pt_ref);
1515 
1516  u=static_cast<data_type>(0.6);
1517  pt_ref=pws.f(u, v);
1518  pt_out=pwc.f(u);
1519  TEST_ASSERT(pt_out==pt_ref);
1520 
1521  u=static_cast<data_type>(0.8);
1522  pt_ref=pws.f(u, v);
1523  pt_out=pwc.f(u);
1524  TEST_ASSERT(pt_out==pt_ref);
1525 
1526  u=1;
1527  pt_ref=pws.f(u, v);
1528  pt_out=pwc.f(u);
1529  TEST_ASSERT(pt_out==pt_ref);
1530 
1531  // Extract v curve
1532  v=static_cast<data_type>(0.1);
1533  pws.get_vconst_curve(pwc, v);
1534 
1535  u=0;
1536  pt_ref=pws.f(u, v);
1537  pt_out=pwc.f(u);
1538  TEST_ASSERT(pt_out==pt_ref);
1539 
1540  u=static_cast<data_type>(0.1);
1541  pt_ref=pws.f(u, v);
1542  pt_out=pwc.f(u);
1543  d=(pt_ref - pt_out).norm();
1544  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1545 
1546  u=static_cast<data_type>(0.2);
1547  pt_ref=pws.f(u, v);
1548  pt_out=pwc.f(u);
1549  TEST_ASSERT(pt_out==pt_ref);
1550 
1551  u=static_cast<data_type>(0.4);
1552  pt_ref=pws.f(u, v);
1553  pt_out=pwc.f(u);
1554  d=(pt_ref - pt_out).norm();
1555  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1556 
1557  u=static_cast<data_type>(0.6);
1558  pt_ref=pws.f(u, v);
1559  pt_out=pwc.f(u);
1560  d=(pt_ref - pt_out).norm();
1561  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1562 
1563  u=static_cast<data_type>(0.8);
1564  pt_ref=pws.f(u, v);
1565  pt_out=pwc.f(u);
1566  d=(pt_ref - pt_out).norm();
1567  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1568 
1569  u=1;
1570  pt_ref=pws.f(u, v);
1571  pt_out=pwc.f(u);
1572  TEST_ASSERT(pt_out==pt_ref);
1573 
1574  // Extract v curve
1575  v=static_cast<data_type>(0.2);
1576  pws.get_vconst_curve(pwc, v);
1577 
1578  u=0;
1579  pt_ref=pws.f(u, v);
1580  pt_out=pwc.f(u);
1581  TEST_ASSERT(pt_out==pt_ref);
1582 
1583  u=static_cast<data_type>(0.1);
1584  pt_ref=pws.f(u, v);
1585  pt_out=pwc.f(u);
1586  TEST_ASSERT(pt_out==pt_ref);
1587 
1588  u=static_cast<data_type>(0.2);
1589  pt_ref=pws.f(u, v);
1590  pt_out=pwc.f(u);
1591  TEST_ASSERT(pt_out==pt_ref);
1592 
1593  u=static_cast<data_type>(0.4);
1594  pt_ref=pws.f(u, v);
1595  pt_out=pwc.f(u);
1596  d=(pt_ref - pt_out).norm();
1597  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1598 
1599  u=static_cast<data_type>(0.6);
1600  pt_ref=pws.f(u, v);
1601  pt_out=pwc.f(u);
1602  d=(pt_ref - pt_out).norm();
1603  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1604 
1605  u=static_cast<data_type>(0.8);
1606  pt_ref=pws.f(u, v);
1607  pt_out=pwc.f(u);
1608  d=(pt_ref - pt_out).norm();
1609  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1610 
1611  u=1;
1612  pt_ref=pws.f(u, v);
1613  pt_out=pwc.f(u);
1614  TEST_ASSERT(pt_out==pt_ref);
1615 
1616  // Extract v curve
1617  v=static_cast<data_type>(0.4);
1618  pws.get_vconst_curve(pwc, v);
1619 
1620  u=0;
1621  pt_ref=pws.f(u, v);
1622  pt_out=pwc.f(u);
1623  TEST_ASSERT(pt_out==pt_ref);
1624 
1625  u=static_cast<data_type>(0.1);
1626  pt_ref=pws.f(u, v);
1627  pt_out=pwc.f(u);
1628  d=(pt_ref - pt_out).norm();
1629  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1630 
1631  u=static_cast<data_type>(0.2);
1632  pt_ref=pws.f(u, v);
1633  pt_out=pwc.f(u);
1634  d=(pt_ref - pt_out).norm();
1635  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1636 
1637  u=static_cast<data_type>(0.4);
1638  pt_ref=pws.f(u, v);
1639  pt_out=pwc.f(u);
1640  d=(pt_ref - pt_out).norm();
1641  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1642 
1643  u=static_cast<data_type>(0.6);
1644  pt_ref=pws.f(u, v);
1645  pt_out=pwc.f(u);
1646  TEST_ASSERT(pt_out==pt_ref);
1647 
1648  u=static_cast<data_type>(0.8);
1649  pt_ref=pws.f(u, v);
1650  pt_out=pwc.f(u);
1651  d=(pt_ref - pt_out).norm();
1652  TEST_ASSERT(d<std::numeric_limits<data_type>::epsilon()*30);
1653 
1654  u=1;
1655  pt_ref=pws.f(u, v);
1656  pt_out=pwc.f(u);
1657  TEST_ASSERT(pt_out==pt_ref);
1658 
1659  // Extract v curve
1660  v=1;
1661  pws.get_vconst_curve(pwc, v);
1662 
1663  u=0;
1664  pt_ref=pws.f(u, v);
1665  pt_out=pwc.f(u);
1666  TEST_ASSERT(pt_out==pt_ref);
1667 
1668  u=static_cast<data_type>(0.1);
1669  pt_ref=pws.f(u, v);
1670  pt_out=pwc.f(u);
1671  TEST_ASSERT(pt_out==pt_ref);
1672 
1673  u=static_cast<data_type>(0.2);
1674  pt_ref=pws.f(u, v);
1675  pt_out=pwc.f(u);
1676  TEST_ASSERT(pt_out==pt_ref);
1677 
1678  u=static_cast<data_type>(0.4);
1679  pt_ref=pws.f(u, v);
1680  pt_out=pwc.f(u);
1681  TEST_ASSERT(pt_out==pt_ref);
1682 
1683  u=static_cast<data_type>(0.6);
1684  pt_ref=pws.f(u, v);
1685  pt_out=pwc.f(u);
1686  TEST_ASSERT(pt_out==pt_ref);
1687 
1688  u=static_cast<data_type>(0.8);
1689  pt_ref=pws.f(u, v);
1690  pt_out=pwc.f(u);
1691  TEST_ASSERT(pt_out==pt_ref);
1692 
1693  u=1;
1694  pt_ref=pws.f(u, v);
1695  pt_out=pwc.f(u);
1696  TEST_ASSERT(pt_out==pt_ref);
1697  }
1698 
1700  {
1701  // create
1702  {
1703  surface_type s;
1704  piecewise_surface_type ps;
1705  std::vector<data_type> du(3), dv(2);
1707 
1708  // set the du and dv
1709  du[0]=0.5;
1710  du[1]=1.5;
1711  du[2]=0.5;
1712  dv[0]=1.25;
1713  dv[1]=0.5;
1714  // create 3x2 patches with unit spacing
1715  ps.init_uv(du.begin(), du.end(), dv.begin(), dv.end(), -1, -2);
1716  TEST_ASSERT(ps.number_u_patches()==3);
1717  TEST_ASSERT(ps.number_v_patches()==2);
1718 
1719  // create and set each surface
1720  index_type i, j, n, m;
1721  point_type pt[3+1][3+1], pt_out;
1722 
1723  // create patch 0,0
1724  n=1;
1725  m=3;
1726  pt[0][0] << -20, 0, 15;
1727  pt[0][1] << -20, 5, 5;
1728  pt[0][2] << -20, 5, -5;
1729  pt[0][3] << -20, 0, -15;
1730  pt[1][0] << -15, 0, 15;
1731  pt[1][1] << -15, 5, 5;
1732  pt[1][2] << -15, 5, -5;
1733  pt[1][3] << -15, 0, -15;
1734  s.resize(n, m);
1735  for (i=0; i<=n; ++i)
1736  {
1737  for (j=0; j<=m; ++j)
1738  {
1739  s.set_control_point(pt[i][j], i, j);
1740  }
1741  }
1742  err=ps.set(s, 0, 0);
1743  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1744 
1745  // create patch 1, 0
1746  n=3;
1747  m=3;
1748  pt[0][0] << -15, 0, 15;
1749  pt[1][0] << -5, 5, 15;
1750  pt[2][0] << 5, 5, 15;
1751  pt[3][0] << 15, 0, 15;
1752  pt[0][1] << -15, 5, 5;
1753  pt[1][1] << -5, 5, 5;
1754  pt[2][1] << 5, 5, 5;
1755  pt[3][1] << 15, 5, 5;
1756  pt[0][2] << -15, 5, -5;
1757  pt[1][2] << -5, 5, -5;
1758  pt[2][2] << 5, 5, -5;
1759  pt[3][2] << 15, 5, -5;
1760  pt[0][3] << -15, 0, -15;
1761  pt[1][3] << -5, 5, -15;
1762  pt[2][3] << 5, 5, -15;
1763  pt[3][3] << 15, 0, -15;
1764  s.resize(n, m);
1765  for (i=0; i<=n; ++i)
1766  {
1767  for (j=0; j<=m; ++j)
1768  {
1769  s.set_control_point(pt[i][j], i, j);
1770  }
1771  }
1772  err=ps.set(s, 1, 0);
1773  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1774 
1775  // create patch 2,0
1776  n=1;
1777  m=3;
1778  pt[0][0] << 15, 0, 15;
1779  pt[0][1] << 15, 5, 5;
1780  pt[0][2] << 15, 5, -5;
1781  pt[0][3] << 15, 0, -15;
1782  pt[1][0] << 20, 0, 15;
1783  pt[1][1] << 20, 5, 5;
1784  pt[1][2] << 20, 5, -5;
1785  pt[1][3] << 20, 0, -15;
1786  s.resize(n, m);
1787  for (i=0; i<=n; ++i)
1788  {
1789  for (j=0; j<=m; ++j)
1790  {
1791  s.set_control_point(pt[i][j], i, j);
1792  }
1793  }
1794  err=ps.set(s, 2, 0);
1795  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1796 
1797  // create patch 0,1
1798  n=1;
1799  m=2;
1800  pt[0][0] << -20, 0, -15;
1801  pt[0][1] << -20, -3, -7;
1802  pt[0][2] << -20, -7, -10;
1803  pt[1][0] << -15, 0, -15;
1804  pt[1][1] << -15, -3, -7;
1805  pt[1][2] << -15, -7, -10;
1806 
1807  s.resize(n, m);
1808  for (i=0; i<=n; ++i)
1809  {
1810  for (j=0; j<=m; ++j)
1811  {
1812  s.set_control_point(pt[i][j], i, j);
1813  }
1814  }
1815  err=ps.set(s, 0, 1);
1816  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1817 
1818  // create patch 1,1
1819  n=3;
1820  m=2;
1821  pt[0][0] << -15, 0, -15;
1822  pt[0][1] << -15, -3, -7;
1823  pt[0][2] << -15, -7, -10;
1824  pt[1][0] << -5, 5, -15;
1825  pt[1][1] << -5, -1, -7;
1826  pt[1][2] << -5, -4, -10;
1827  pt[2][0] << 5, 5, -15;
1828  pt[2][1] << 5, -1, -7;
1829  pt[2][2] << 5, -4, -10;
1830  pt[3][0] << 15, 0, -15;
1831  pt[3][1] << 15, -3, -7;
1832  pt[3][2] << 15, -7, -10;
1833 
1834  s.resize(n, m);
1835  for (i=0; i<=n; ++i)
1836  {
1837  for (j=0; j<=m; ++j)
1838  {
1839  s.set_control_point(pt[i][j], i, j);
1840  }
1841  }
1842  err=ps.set(s, 1, 1);
1843  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1844 
1845  // create patch 2,1
1846  n=1;
1847  m=2;
1848  pt[0][0] << 15, 0, -15;
1849  pt[0][1] << 15, -3, -7;
1850  pt[0][2] << 15, -7, -10;
1851  pt[1][0] << 20, 0, -15;
1852  pt[1][1] << 20, -3, -7;
1853  pt[1][2] << 20, -7, -10;
1854 
1855  s.resize(n, m);
1856  for (i=0; i<=n; ++i)
1857  {
1858  for (j=0; j<=m; ++j)
1859  {
1860  s.set_control_point(pt[i][j], i, j);
1861  }
1862  }
1863  err=ps.set(s, 2, 1);
1864  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1865 
1866  std::vector<data_type> ujoints(2*ps.number_u_patches()+1), vjoints(2*ps.number_v_patches()+1);
1867  std::vector<data_type> disc_ujoints, disc_ujoints_ref(2), disc_vjoints, disc_vjoints_ref(1);
1868  tolerance_type tol;
1869 
1870  // store joints
1871  ujoints[0]=ps.get_u0();
1872  ujoints[1]=ujoints[0]+du[0]/2;
1873  ujoints[2]=ujoints[0]+du[0];
1874  ujoints[3]=ujoints[2]+du[1]/2;
1875  ujoints[4]=ujoints[2]+du[1];
1876  ujoints[5]=ujoints[4]+du[2]/2;
1877  ujoints[6]=ujoints[4]+du[2];
1878  vjoints[0]=ps.get_v0();
1879  vjoints[1]=vjoints[0]+dv[0]/2;
1880  vjoints[2]=vjoints[0]+dv[0];
1881  vjoints[3]=vjoints[2]+dv[1]/2;
1882  vjoints[4]=vjoints[2]+dv[1];
1883 
1884  // store the discontinuous joints
1885  disc_ujoints_ref[0]=ujoints[2];
1886  disc_ujoints_ref[1]=ujoints[4];
1887  disc_vjoints_ref[0]=vjoints[2];
1888 
1889  // split curve at 3 locations to create continuous joints
1890  ps.split_u(ujoints[1]);
1891  ps.split_u(ujoints[3]);
1892  ps.split_u(ujoints[5]);
1893  ps.split_v(vjoints[1]);
1894  ps.split_v(vjoints[3]);
1895  TEST_ASSERT(ps.number_u_patches()==6);
1896  TEST_ASSERT(ps.number_v_patches()==4);
1897 
1898 // if (typeid(data_type)==typeid(float))
1899 // {
1900 // octave_print(1, ps);
1901 // }
1902 
1903  ps.find_interior_C0_edges(disc_ujoints, disc_vjoints);
1904  TEST_ASSERT(disc_ujoints.size()==disc_ujoints_ref.size());
1905  TEST_ASSERT(disc_vjoints.size()==disc_vjoints_ref.size());
1906  TEST_ASSERT(tol.approximately_equal(disc_ujoints[0], disc_ujoints_ref[0]));
1907  TEST_ASSERT(tol.approximately_equal(disc_ujoints[1], disc_ujoints_ref[1]));
1908  TEST_ASSERT(tol.approximately_equal(disc_vjoints[0], disc_vjoints_ref[0]));
1909  }
1910  }
1911 };
1912 
1913 #endif
1914 
void to_cubic(const data_type &ttol)
Definition: piecewise.hpp:720
surface_type::point_type point_type
Definition: piecewise.hpp:59
void split_test()
Definition: piecewise_surface_test_suite.hpp:892
void AddTests(const float &)
Definition: piecewise_surface_test_suite.hpp:48
void reverse_u()
Definition: piecewise.hpp:421
void replace_test()
Definition: piecewise_surface_test_suite.hpp:601
tolerance_type tol
Definition: piecewise_surface_test_suite.hpp:45
piecewise_surface_type::surface_type surface_type
Definition: piecewise_surface_test_suite.hpp:38
void translate(const point_type &trans)
Definition: piecewise.hpp:407
data__ data_type
Definition: piecewise.hpp:66
point_type f_u(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:910
data_type get_u0() const
Definition: piecewise.hpp:133
void get_parameter_max(data_type &umax, data_type &vmax) const
Definition: piecewise.hpp:175
void get_uconst_curve(piecewise_curve_type &pwc, const data_type &u) const
Definition: piecewise.hpp:726
error_code get(surface_type &surf, const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:487
eli::geom::surface::piecewise< eli::geom::surface::bezier, data__, 3 > piecewise_surface_type
Definition: piecewise_surface_test_suite.hpp:37
point_type f(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:897
index_type number_v_patches() const
Definition: piecewise.hpp:143
void to_cubic_v(const data_type &ttol)
Definition: piecewise.hpp:674
void transformation_test()
Definition: piecewise_surface_test_suite.hpp:688
piecewise_surface_test_suite()
Definition: piecewise_surface_test_suite.hpp:98
Definition: piecewise.hpp:37
void reverse_v()
Definition: piecewise.hpp:436
point_type f_vv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:975
void swap_test()
Definition: piecewise_surface_test_suite.hpp:516
void bounding_box_test()
Definition: piecewise_surface_test_suite.hpp:346
void to_cubic_test()
Definition: piecewise_surface_test_suite.hpp:1011
error_code replace(const surface_type &surf, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:524
void reverse_test()
Definition: piecewise_surface_test_suite.hpp:416
error_code split_u(const data_type &u_in)
Definition: piecewise.hpp:582
void find_interior_C0_edges(std::vector< data_type > &uconst, std::vector< data_type > &vconst) const
Definition: piecewise.hpp:842
tol__ tolerance_type
Definition: piecewise.hpp:68
void octave_print(int figno, const piecewise_surface_type &ps) const
Definition: piecewise_surface_test_suite.hpp:107
error_code split_v(const data_type &v_in)
Definition: piecewise.hpp:605
void rotate(const rotation_matrix_type &rmat)
Definition: piecewise.hpp:379
void swap_uv()
Definition: piecewise.hpp:451
error_code
Definition: piecewise.hpp:69
void length(typename piecewise< curve__, data__, dim__, tol__ >::data_type &len, const piecewise< curve__, data__, dim__, tol__ > &pc, const typename piecewise< curve__, data__, dim__, tol__ >::data_type &tol)
Definition: length.hpp:43
point_type f_uu(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:942
data_type get_v0() const
Definition: piecewise.hpp:136
piecewise_surface_type::data_type data_type
Definition: piecewise_surface_test_suite.hpp:40
void get_parameter_min(data_type &umin, data_type &vmin) const
Definition: piecewise.hpp:169
void get_curve_test()
Definition: piecewise_surface_test_suite.hpp:1239
point_type f_uv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:958
surface_type::index_type index_type
Definition: piecewise.hpp:58
void to_cubic_u(const data_type &ttol)
Definition: piecewise.hpp:628
void AddTests(const long double &)
Definition: piecewise_surface_test_suite.hpp:80
index_type number_u_patches() const
Definition: piecewise.hpp:142
Definition: piecewise.hpp:71
piecewise_surface_type::point_type point_type
Definition: piecewise_surface_test_suite.hpp:39
Definition: piecewise_surface_test_suite.hpp:34
void continuity_test()
Definition: piecewise_surface_test_suite.hpp:1699
void area_test()
Definition: piecewise_surface_test_suite.hpp:1158
surface_type::bounding_box_type bounding_box_type
Definition: piecewise.hpp:62
surface_type::rotation_matrix_type rotation_matrix_type
Definition: piecewise.hpp:61
point_type f(const data_type &t) const
Definition: piecewise.hpp:1732
void evaluation_test()
Definition: piecewise_surface_test_suite.hpp:793
void init_uv(const index_type &nsegu, const index_type &nsegv, const data_type &du=1, const data_type &dv=1, const data_type &u0=0, const data_type &v0=0)
Definition: piecewise.hpp:219
~piecewise_surface_test_suite()
Definition: piecewise_surface_test_suite.hpp:102
void get_vconst_curve(piecewise_curve_type &pwc, const data_type &v) const
Definition: piecewise.hpp:756
piecewise_surface_type::tolerance_type tolerance_type
Definition: piecewise_surface_test_suite.hpp:42
void AddTests(const double &)
Definition: piecewise_surface_test_suite.hpp:64
void get_bounding_box(bounding_box_type &bb) const
Definition: piecewise.hpp:360
surface__< data__, dim__, tol__ > surface_type
Definition: piecewise.hpp:57
error_code set(const surface_type &surf, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:509
piecewise_surface_type::piecewise_curve_type piecewise_curve_type
Definition: piecewise_surface_test_suite.hpp:43
void creation_test()
Definition: piecewise_surface_test_suite.hpp:266
piecewise_surface_type::index_type index_type
Definition: piecewise_surface_test_suite.hpp:41
void degree_u(index_type &mind, index_type &maxd)
Definition: piecewise.hpp:252
point_type f_v(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:926