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