Code-Eli  0.3.6
minimum_distance_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 minimum_distance_curve_test_suite_hpp
14 #define minimum_distance_curve_test_suite_hpp
15 
16 #include <cmath> // cos(), sin()
17 
18 #include <typeinfo> // typeid
19 
23 
24 template<typename data__>
25 class minimum_distance_curve_test_suite : public Test::Suite
26 {
27  private:
28  typedef data__ data_type;
29 
33 
36  typedef typename curve_type3::point_type point_type3;
37  typedef typename curve_type3::index_type index_type3;
38 
40 
41  tolerance_type tol;
42 
43  protected:
44  void AddTests(const float &)
45  {
46  // add the tests
53  }
54  void AddTests(const double &)
55  {
56  // add the tests
63  }
64  void AddTests(const long double &)
65  {
66  // add the tests
73  }
74 
75  public:
77  {
78  AddTests(data__());
79  }
81  {
82  }
83 
84  private:
85  void octave_print(int figno, const std::vector<point_type2> &pts, const curve_type2 &c) const
86  {
87  size_t i;
88 
89  std::cout << "figure(" << figno << ");" << std::endl;
90  std::cout << "xpts=[" << pts[0].x();
91  for (i=1; i<pts.size(); ++i)
92  std::cout << ", " << pts[i].x();
93  std::cout << "];" << std::endl;
94  std::cout << "ypts=[" << pts[0].y();
95  for (i=1; i<pts.size(); ++i)
96  std::cout << ", " << pts[i].y();
97  std::cout << "];" << std::endl;
98 
99  std::vector<data__> t(101);
100  for (i=0; i<t.size(); ++i)
101  t[i]=static_cast<data__>(i)/(t.size()-1);
102 
103  std::cout << "xint=[" << c.f(t[0])(0);
104  for (i=1; i<t.size(); ++i)
105  std::cout << ", " << c.f(t[i])(0);
106  std::cout << "];" << std::endl;
107  std::cout << "yint=[" << c.f(t[0])(1);
108  for (i=1; i<t.size(); ++i)
109  std::cout << ", " << c.f(t[i])(1);
110  std::cout << "];" << std::endl;
111 
112  std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
113  std::cout << "plot(xpts, ypts, 'bo', xint, yint, 'k-');" << std::endl;
114 
115  std::cout << "figure(" << figno+1 << ");" << std::endl;
116  std::cout << "t=[" << t[0];
117  for (i=1; i<t.size(); ++i)
118  std::cout << ", " << t[i];
119  std::cout << "];" << std::endl;
120  std::cout << "g=[" << (c.f(t[0])-pts[0]).dot(c.fp(t[0]));
121  for (i=1; i<t.size(); ++i)
122  std::cout << ", " << (c.f(t[i])-pts[0]).dot(c.fp(t[i]));
123  std::cout << "];" << std::endl;
124 
125  std::cout << "plot([0,1], [0, 0], 'k-', t, g, 'k-');" << std::endl;
126  }
127 
128  void octave_print(int figno, const std::vector<point_type3> &pts, const curve_type3 &c) const
129  {
130  size_t i;
131 
132  std::cout << std::endl;
133  std::cout << "figure(" << figno << ");" << std::endl;
134  std::cout << "xpts=[" << pts[0].x();
135  for (i=1; i<pts.size(); ++i)
136  std::cout << ", " << pts[i].x();
137  std::cout << "];" << std::endl;
138  std::cout << "ypts=[" << pts[0].y();
139  for (i=1; i<pts.size(); ++i)
140  std::cout << ", " << pts[i].y();
141  std::cout << "];" << std::endl;
142  std::cout << "zpts=[" << pts[0].z();
143  for (i=1; i<pts.size(); ++i)
144  std::cout << ", " << pts[i].z();
145  std::cout << "];" << std::endl;
146 
147  std::vector<data__> t(101);
148  for (i=0; i<t.size(); ++i)
149  t[i]=static_cast<data__>(i)/(t.size()-1);
150 
151  std::cout << "xint=[" << c.f(t[0]).x();
152  for (i=1; i<t.size(); ++i)
153  std::cout << ", " << c.f(t[i]).x();
154  std::cout << "];" << std::endl;
155  std::cout << "yint=[" << c.f(t[0]).y();
156  for (i=1; i<t.size(); ++i)
157  std::cout << ", " << c.f(t[i]).y();
158  std::cout << "];" << std::endl;
159  std::cout << "zint=[" << c.f(t[0]).z();
160  for (i=1; i<t.size(); ++i)
161  std::cout << ", " << c.f(t[i]).z();
162  std::cout << "];" << std::endl;
163 
164  std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
165  std::cout << "plot3(xpts, ypts, zpts, 'bo', xint, yint, zint, 'k-');" << std::endl;
166  std::cout << "axis equal" << std::endl;
167 
168  std::cout << "figure(" << figno+1 << ");" << std::endl;
169  std::cout << "t=[" << t[0];
170  for (i=1; i<t.size(); ++i)
171  std::cout << ", " << t[i];
172  std::cout << "];" << std::endl;
173  std::cout << "g=[" << (c.f(t[0])-pts[0]).dot(c.fp(t[0]));
174  for (i=1; i<t.size(); ++i)
175  std::cout << ", " << (c.f(t[i])-pts[0]).dot(c.fp(t[i]));
176  std::cout << "];" << std::endl;
177 
178  std::cout << "plot([0,1], [0, 0], 'k-', t, g, 'k-');" << std::endl << std::endl;
179  }
180 
182  {
183  point_type2 cntrl_in[4];
184 
185  // set control points
186  cntrl_in[0] <<-1, 2;
187  cntrl_in[1] << 0, 1;
188  cntrl_in[2] << 3, 0;
189  cntrl_in[3] << 4, 1;
190 
191  curve_type2 c(3);
192  point_type2 pt, norm;
193  data_type dist, t, dist_ref, t_ref;
194 
195  // set control points
196  for (index_type2 i=0; i<4; ++i)
197  {
198  c.set_control_point(cntrl_in[i], i);
199  }
200 
201  // test point on curve
202  dist_ref=0;
203  t_ref=0.25;
204  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
205  norm.normalize();
206  pt=c.f(t_ref)+dist_ref*norm;
208  TEST_ASSERT(tol.approximately_equal(t, t_ref));
209  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
210 
211  // test point very near curve
212  dist_ref=static_cast<data_type>(0.01);
213  t_ref=0.25;
214  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
215  norm.normalize();
216  pt=c.f(t_ref)+dist_ref*norm;
218  TEST_ASSERT(tol.approximately_equal(t, t_ref));
219  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
220 
221  // test point near curve
222  dist_ref=static_cast<data_type>(0.1);
223  t_ref=0.25;
224  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
225  norm.normalize();
226  pt=c.f(t_ref)+dist_ref*norm;
228  TEST_ASSERT(tol.approximately_equal(t, t_ref));
229  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
230 
231  // test point far from curve
232  dist_ref=static_cast<data_type>(1.5);
233  t_ref=0.25;
234  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
235  norm.normalize();
236  pt=c.f(t_ref)+dist_ref*norm;
238  TEST_ASSERT(tol.approximately_equal(t, t_ref));
239  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
240 
241  // test point on curve
242  dist_ref=0;
243  t_ref=static_cast<data_type>(0.6);
244  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
245  norm.normalize();
246  pt=c.f(t_ref)+dist_ref*norm;
248  TEST_ASSERT(tol.approximately_equal(t, t_ref));
249  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
250 
251  // test point near curve
252  dist_ref=static_cast<data_type>(0.1);
253  t_ref=static_cast<data_type>(0.65);
254  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
255  norm.normalize();
256  pt=c.f(t_ref)+dist_ref*norm;
258  TEST_ASSERT(tol.approximately_equal(t, t_ref));
259  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
260 
261  // test point near end of curve
262  dist_ref=static_cast<data_type>(0.1);
263  t_ref=static_cast<data_type>(0.01);
264  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
265  norm.normalize();
266  pt=c.f(t_ref)+dist_ref*norm;
268  TEST_ASSERT(tol.approximately_equal(t, t_ref));
269  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
270 
271  // test point very near end of curve
272  dist_ref=static_cast<data_type>(0.1);
273  t_ref=static_cast<data_type>(0.001);
274  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
275  norm.normalize();
276  pt=c.f(t_ref)+dist_ref*norm;
278  TEST_ASSERT(tol.approximately_equal(t, t_ref));
279  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
280 
281  // test point very near end of curve
282  dist_ref=static_cast<data_type>(0.1);
283  t_ref=static_cast<data_type>(0.999);
284  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
285  norm.normalize();
286  pt=c.f(t_ref)+dist_ref*norm;
288  TEST_ASSERT(tol.approximately_equal(t, t_ref));
289  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
290 
291  // test point beyond start of curve
292  t_ref=static_cast<data_type>(0);
293  pt << -2, 2;
294  dist_ref=(cntrl_in[0]-pt).norm();
296  TEST_ASSERT(tol.approximately_equal(t, t_ref));
297  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
298 
299  // test point beyond end of curve
300  t_ref=static_cast<data_type>(1);
301  pt << 5, 2;
302  dist_ref=(cntrl_in[3]-pt).norm();
304  TEST_ASSERT(tol.approximately_equal(t, t_ref));
305  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
306  }
307 
309  {
310  point_type2 cntrl_in[13];
311 
312  // set control points
313  cntrl_in[0] << 1, 0;
314  cntrl_in[1] << 1, 0.5;
315  cntrl_in[2] << 0.5, 1;
316  cntrl_in[3] << 0, 1;
317  cntrl_in[4] <<-0.5, 1;
318  cntrl_in[5] << -1, 0.5;
319  cntrl_in[6] << -1, 0;
320  cntrl_in[7] << -1,-0.5;
321  cntrl_in[8] <<-0.5,-1;
322  cntrl_in[9] << 0,-1;
323  cntrl_in[10] << 0.5,-1;
324  cntrl_in[11] << 1,-0.5;
325  cntrl_in[12] << 1,0;
326 
327  curve_type2 c(12);
328  point_type2 pt, norm;
329  data_type dist, t, dist_ref, t_ref;
330 
331  // set control points
332  for (index_type2 i=0; i<13; ++i)
333  {
334  c.set_control_point(cntrl_in[i], i);
335  }
336 
337  // test point on curve
338  dist_ref=0;
339  t_ref=0.25;
340  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
341  norm.normalize();
342  pt=c.f(t_ref)+dist_ref*norm;
344  TEST_ASSERT(tol.approximately_equal(t, t_ref));
345  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
346 
347  // test point near curve
348  dist_ref=static_cast<data_type>(0.1);
349  t_ref=0.25;
350  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
351  norm.normalize();
352  pt=c.f(t_ref)+dist_ref*norm;
354  TEST_ASSERT(tol.approximately_equal(t, t_ref));
355  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
356 
357  // test point near center
358  dist_ref=static_cast<data_type>(0.77);
359  t_ref=0.25;
360  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
361  norm.normalize();
362  pt=c.f(t_ref)+dist_ref*norm;
364  TEST_ASSERT(tol.approximately_equal(t, t_ref));
365  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
366 
367  // test point near and outside curve
368  dist_ref=static_cast<data_type>(0.1);
369  t_ref=static_cast<data_type>(0.7);
370  norm << c.fp(t_ref).y(), -c.fp(t_ref).x();
371  norm.normalize();
372  pt=c.f(t_ref)+dist_ref*norm;
374  TEST_ASSERT(tol.approximately_equal(t, t_ref));
375  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
376 
377  // test point far and outside curve
378  dist_ref=3;
379  t_ref=static_cast<data_type>(0.7);
380  norm << c.fp(t_ref).y(), -c.fp(t_ref).x();
381  norm.normalize();
382  pt=c.f(t_ref)+dist_ref*norm;
384  TEST_ASSERT(tol.approximately_equal(t, t_ref));
385  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
386 
387  // test point near end of curve
388  dist_ref=static_cast<data_type>(0.1);
389  t_ref=static_cast<data_type>(0.999);
390  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
391  norm.normalize();
392  pt=c.f(t_ref)+dist_ref*norm;
394  TEST_ASSERT(tol.approximately_equal(t, t_ref));
395  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
396 
397  // test point near end of and outside curve
398  dist_ref=static_cast<data_type>(0.1);
399  t_ref=static_cast<data_type>(0.999);
400  norm << c.fp(t_ref).y(), -c.fp(t_ref).x();
401  norm.normalize();
402  pt=c.f(t_ref)+dist_ref*norm;
404  TEST_ASSERT(tol.approximately_equal(t, t_ref));
405  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
406 
407  // test point near start of curve
408  dist_ref=static_cast<data_type>(0.1);
409  t_ref=static_cast<data_type>(0.001);
410  norm << -c.fp(t_ref).y(), c.fp(t_ref).x();
411  norm.normalize();
412  pt=c.f(t_ref)+dist_ref*norm;
414  TEST_ASSERT(tol.approximately_equal(t, t_ref));
415  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
416 
417  // test point near start of and outside curve
418  dist_ref=static_cast<data_type>(0.1);
419  t_ref=static_cast<data_type>(0.001);
420  norm << c.fp(t_ref).y(), -c.fp(t_ref).x();
421  norm.normalize();
422  pt=c.f(t_ref)+dist_ref*norm;
424  TEST_ASSERT(tol.approximately_equal(t, t_ref));
425  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
426 
427  // test point near start of and far outside curve
428  dist_ref=3;
429  t_ref=static_cast<data_type>(0.001);
430  norm << c.fp(t_ref).y(), -c.fp(t_ref).x();
431  norm.normalize();
432  pt=c.f(t_ref)+dist_ref*norm;
434  TEST_ASSERT(tol.approximately_equal(t, t_ref));
435  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
436  }
437 
439  {
440  point_type3 cntrl_in[4];
441 
442  // set control points
443  cntrl_in[0] <<-1, 2, 1;
444  cntrl_in[1] << 0, 1, 0;
445  cntrl_in[2] << 3, 0, 1;
446  cntrl_in[3] << 4, 1, 2;
447 
448  curve_type3 c(3);
449  point_type3 pt, fp, norm;
450  data_type dist, t, dist_ref, t_ref, t_guess;
451 
452  // set control points
453  for (index_type2 i=0; i<4; ++i)
454  {
455  c.set_control_point(cntrl_in[i], i);
456  }
457 
458  // test point on curve
459  dist_ref=0;
460  t_ref=0.25;
461  fp=c.fp(t_ref);
462  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
463  norm.normalize();
464  pt=c.f(t_ref)+dist_ref*norm;
465 
466  t_guess=t_ref;
467  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
468  TEST_ASSERT(tol.approximately_equal(t, t_ref));
469  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
470 
471  t_guess=t_ref+static_cast<data_type>(0.2);
472  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
473  TEST_ASSERT(tol.approximately_equal(t, t_ref));
474  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
475 
476  t_guess=t_ref-static_cast<data_type>(0.2);
477  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
478  TEST_ASSERT(tol.approximately_equal(t, t_ref));
479  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
480 
481  t_guess=0;
482  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
483  TEST_ASSERT(tol.approximately_equal(t, t_ref));
484  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
485 
486 // Case fails because Newton's method seeks local maximum.
487 // t_guess=1;
488 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
489 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
490 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
491 
493  TEST_ASSERT(tol.approximately_equal(t, t_ref));
494  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
495 
496  // test point very near curve
497  dist_ref=static_cast<data_type>(0.01);
498  t_ref=0.25;
499  fp=c.fp(t_ref);
500  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
501  norm.normalize();
502  pt=c.f(t_ref)+dist_ref*norm;
503 
504  t_guess=t_ref;
505  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
506  TEST_ASSERT(tol.approximately_equal(t, t_ref));
507  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
508 
509  t_guess=t_ref+static_cast<data_type>(0.2);
510  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
511  TEST_ASSERT(tol.approximately_equal(t, t_ref));
512  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
513 
514  t_guess=t_ref-static_cast<data_type>(0.2);
515  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
516  TEST_ASSERT(tol.approximately_equal(t, t_ref));
517  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
518 
519  t_guess=0;
520  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
521  TEST_ASSERT(tol.approximately_equal(t, t_ref));
522  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
523 
524 // Case fails because Newton's method seeks local maximum.
525 // t_guess=1;
526 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
527 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
528 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
529 
531  TEST_ASSERT(tol.approximately_equal(t, t_ref));
532  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
533 
534  // test point near curve
535  dist_ref=static_cast<data_type>(0.1);
536  t_ref=0.25;
537  fp=c.fp(t_ref);
538  norm << fp.z(),-fp.z(), -fp.x()+fp.y();
539  norm.normalize();
540  pt=c.f(t_ref)+dist_ref*norm;
541 
542  t_guess=t_ref;
543  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
544  TEST_ASSERT(tol.approximately_equal(t, t_ref));
545  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
546 
547  t_guess=t_ref+static_cast<data_type>(0.2);
548  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
549  TEST_ASSERT(tol.approximately_equal(t, t_ref));
550  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
551 
552  t_guess=t_ref-static_cast<data_type>(0.2);
553  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
554  TEST_ASSERT(tol.approximately_equal(t, t_ref));
555  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
556 
557  t_guess=0;
558  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
559  TEST_ASSERT(tol.approximately_equal(t, t_ref));
560  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
561 
562 // Case fails because Newton's method seeks local maximum.
563 // t_guess=1;
564 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
565 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
566 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
567 
569  TEST_ASSERT(tol.approximately_equal(t, t_ref));
570  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
571 
572  // test point far from curve
573  dist_ref=static_cast<data_type>(1.5);
574  t_ref=0.25;
575  fp=c.fp(t_ref);
576  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
577  norm.normalize();
578  pt=c.f(t_ref)+dist_ref*norm;
579 
580  t_guess=t_ref;
581  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
582  TEST_ASSERT(tol.approximately_equal(t, t_ref));
583  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
584 
585  t_guess=t_ref+static_cast<data_type>(0.2);
586  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
587  TEST_ASSERT(tol.approximately_equal(t, t_ref));
588  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
589 
590  t_guess=t_ref-static_cast<data_type>(0.2);
591  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
592  TEST_ASSERT(tol.approximately_equal(t, t_ref));
593  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
594 
595  t_guess=0;
596  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
597  TEST_ASSERT(tol.approximately_equal(t, t_ref));
598  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
599 
600 // Case fails because Newton's method seeks local maximum.
601 // t_guess=1;
602 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
603 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
604 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
605 
607  TEST_ASSERT(tol.approximately_equal(t, t_ref));
608  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
609 
610  // test point on curve
611  dist_ref=0;
612  t_ref=static_cast<data_type>(0.6);
613  fp=c.fp(t_ref);
614  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
615  norm.normalize();
616  pt=c.f(t_ref)+dist_ref*norm;
617 
618  t_guess=t_ref;
619  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
620  TEST_ASSERT(tol.approximately_equal(t, t_ref));
621  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
622 
623  t_guess=t_ref+static_cast<data_type>(0.2);
624  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
625  TEST_ASSERT(tol.approximately_equal(t, t_ref));
626  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
627 
628  t_guess=t_ref-static_cast<data_type>(0.2);
629  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
630  TEST_ASSERT(tol.approximately_equal(t, t_ref));
631  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
632 
633 // Case fails because Newton's method seeks local maximum.
634 // t_guess=0;
635 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
636 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
637 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
638 
639 // Case fails because Newton's method seeks local maximum.
640 // t_guess=1;
641 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
642 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
643 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
644 
646  TEST_ASSERT(tol.approximately_equal(t, t_ref));
647  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
648 
649  // test point near curve
650  dist_ref=static_cast<data_type>(0.1);
651  t_ref=static_cast<data_type>(0.65);
652  fp=c.fp(t_ref);
653  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
654  norm.normalize();
655  pt=c.f(t_ref)+dist_ref*norm;
656 
657  t_guess=t_ref;
658  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
659  TEST_ASSERT(tol.approximately_equal(t, t_ref));
660  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
661 
662  t_guess=t_ref+static_cast<data_type>(0.2);
663  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
664  TEST_ASSERT(tol.approximately_equal(t, t_ref));
665  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
666 
667  t_guess=t_ref-static_cast<data_type>(0.2);
668  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
669  TEST_ASSERT(tol.approximately_equal(t, t_ref));
670  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
671 
672 // Case fails because Newton's method seeks local maximum.
673 // t_guess=0;
674 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
675 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
676 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
677 
678  t_guess=1;
679  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
680  TEST_ASSERT(tol.approximately_equal(t, t_ref));
681  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
682 
684  TEST_ASSERT(tol.approximately_equal(t, t_ref));
685  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
686 
687  // test point near end of curve
688  dist_ref=static_cast<data_type>(0.1);
689  t_ref=static_cast<data_type>(0.01);
690  fp=c.fp(t_ref);
691  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
692  norm.normalize();
693  pt=c.f(t_ref)+dist_ref*norm;
694 
695  t_guess=t_ref;
696  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
697  TEST_ASSERT(tol.approximately_equal(t, t_ref));
698  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
699 
700  t_guess=t_ref+static_cast<data_type>(0.2);
701  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
702  TEST_ASSERT(tol.approximately_equal(t, t_ref));
703  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
704 
705  t_guess=t_ref-t_ref/2;
706  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
707  TEST_ASSERT(tol.approximately_equal(t, t_ref));
708  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
709 
710  t_guess=0;
711  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
712  TEST_ASSERT(tol.approximately_equal(t, t_ref));
713  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
714 
715 // Case fails because Newton's method seeks local maximum.
716 // t_guess=1;
717 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
718 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
719 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
720 
722  TEST_ASSERT(tol.approximately_equal(t, t_ref));
723  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
724 
725  // test point very near end of curve
726  dist_ref=static_cast<data_type>(0.1);
727  t_ref=static_cast<data_type>(0.001);
728  fp=c.fp(t_ref);
729  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
730  norm.normalize();
731  pt=c.f(t_ref)+dist_ref*norm;
732 
733  t_guess=t_ref;
734  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
735  TEST_ASSERT(tol.approximately_equal(t, t_ref));
736  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
737 
738  t_guess=t_ref+static_cast<data_type>(0.2);
739  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
740  TEST_ASSERT(tol.approximately_equal(t, t_ref));
741  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
742 
743  t_guess=t_ref-t_ref/2;
744  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
745  TEST_ASSERT(tol.approximately_equal(t, t_ref));
746  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
747 
748  t_guess=0;
749  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
750  TEST_ASSERT(tol.approximately_equal(t, t_ref));
751  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
752 
753 // Case fails because Newton's method seeks local maximum.
754 // t_guess=1;
755 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
756 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
757 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
758 
760  TEST_ASSERT(tol.approximately_equal(t, t_ref));
761  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
762 
763  // test point very near end of curve
764  dist_ref=static_cast<data_type>(0.1);
765  t_ref=static_cast<data_type>(0.999);
766  fp=c.fp(t_ref);
767  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
768  norm.normalize();
769  pt=c.f(t_ref)+dist_ref*norm;
770 
771  t_guess=t_ref;
772  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
773  TEST_ASSERT(tol.approximately_equal(t, t_ref));
774  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
775 
776  t_guess=t_ref+(1-t_ref)/2;
777  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
778  TEST_ASSERT(tol.approximately_equal(t, t_ref));
779  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
780 
781  t_guess=t_ref-static_cast<data_type>(0.2);
782  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
783  TEST_ASSERT(tol.approximately_equal(t, t_ref));
784  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
785 
786 // Case fails because Newton's method seeks local maximum.
787 // t_guess=0;
788 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
789 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
790 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
791 
792  t_guess=1;
793  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
794  TEST_ASSERT(tol.approximately_equal(t, t_ref));
795  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
796 
798  TEST_ASSERT(tol.approximately_equal(t, t_ref));
799  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
800 
801  // test point beyond start of curve
802  t_ref=static_cast<data_type>(0);
803  pt << -2, 2, 3;
804  dist_ref=(cntrl_in[0]-pt).norm();
805 
806  t_guess=t_ref;
807  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
808  TEST_ASSERT(tol.approximately_equal(t, t_ref));
809  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
810 
811 // Case fails because Newton's method seeks local maximum.
812 // t_guess=t_ref+static_cast<data_type>(0.2);
813 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
814 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
815 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
816 
817  t_guess=0;
818  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
819  TEST_ASSERT(tol.approximately_equal(t, t_ref));
820  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
821 
822 // Case fails because Newton's method seeks local maximum.
823 // t_guess=1;
824 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
825 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
826 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
827 
829  TEST_ASSERT(tol.approximately_equal(t, t_ref));
830  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
831 
832  // test point beyond end of curve
833  t_ref=static_cast<data_type>(1);
834  pt << 5, 2, 1;
835  dist_ref=(cntrl_in[3]-pt).norm();
836 
837  t_guess=t_ref;
838  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
839  TEST_ASSERT(tol.approximately_equal(t, t_ref));
840  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
841 
842 // Case fails because Newton's method seeks local maximum.
843 // t_guess=t_ref-static_cast<data_type>(0.2);
844 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
845 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
846 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
847 
848 // Case fails because Newton's method seeks local maximum.
849 // t_guess=0;
850 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
851 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
852 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
853 
854  t_guess=1;
855  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
856  TEST_ASSERT(tol.approximately_equal(t, t_ref));
857  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
858 
860  TEST_ASSERT(tol.approximately_equal(t, t_ref));
861  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
862  }
863 
865  {
866  point_type3 cntrl_in[13];
867 
868  // set control points
869  cntrl_in[0] << 1, 0, 0;
870  cntrl_in[1] << 1, 0.5,-0.5;
871  cntrl_in[2] << 0.5, 1, -0.5;
872  cntrl_in[3] << 0, 1, 0;
873  cntrl_in[4] <<-0.5, 1, 0;
874  cntrl_in[5] << -1, 0.5, 0.5;
875  cntrl_in[6] << -1, 0, 0.5;
876  cntrl_in[7] << -1,-0.5, 0;
877  cntrl_in[8] <<-0.5,-1, -0.5;
878  cntrl_in[9] << 0,-1, 0;
879  cntrl_in[10] << 0.5,-1, 0.5;
880  cntrl_in[11] << 1,-0.5, 0.5;
881  cntrl_in[12] << 1,0, 0;
882 
883  curve_type3 c(12);
884  point_type3 pt, norm, fp;
885  data_type dist, t, dist_ref, t_ref, t_guess;
886 
887  // set control points
888  for (index_type3 i=0; i<13; ++i)
889  {
890  c.set_control_point(cntrl_in[i], i);
891  }
892 
893  // test point on curve
894  dist_ref=0;
895  t_ref=0.25;
896  fp=c.fp(t_ref);
897  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
898  norm.normalize();
899  pt=c.f(t_ref)+dist_ref*norm;
900 
901  t_guess=t_ref;
902  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
903  TEST_ASSERT(tol.approximately_equal(t, t_ref));
904  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
905 
906  t_guess=t_ref+static_cast<data_type>(0.2);
907  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
908  TEST_ASSERT(tol.approximately_equal(t, t_ref));
909  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
910 
911 // Newton's method does not converge.
912 // t_guess=t_ref-static_cast<data_type>(0.2);
913 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
914 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
915 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
916 
917  t_guess=0;
918  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
919  TEST_ASSERT(tol.approximately_equal(t, t_ref));
920  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
921 
922  t_guess=1;
923  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
924  TEST_ASSERT(tol.approximately_equal(t, t_ref));
925  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
926 
928  TEST_ASSERT(tol.approximately_equal(t, t_ref));
929  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
930 
931  // test point near curve
932  dist_ref=static_cast<data_type>(0.1);
933  t_ref=0.25;
934  fp=c.fp(t_ref);
935  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
936  norm.normalize();
937  pt=c.f(t_ref)+dist_ref*norm;
938 
939  t_guess=t_ref;
940  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
941  TEST_ASSERT(tol.approximately_equal(t, t_ref));
942  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
943 
944  t_guess=t_ref+static_cast<data_type>(0.2);
945  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
946  TEST_ASSERT(tol.approximately_equal(t, t_ref));
947  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
948 
949  t_guess=t_ref-static_cast<data_type>(0.2);
950  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
951  TEST_ASSERT(tol.approximately_equal(t, t_ref));
952  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
953 
954 // Newton's method does not converge.
955 // t_guess=0;
956 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
957 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
958 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
959 
960  t_guess=1;
961  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
962  TEST_ASSERT(tol.approximately_equal(t, t_ref));
963  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
964 
966  TEST_ASSERT(tol.approximately_equal(t, t_ref));
967  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
968 
969  // test point near center
970  dist_ref=static_cast<data_type>(0.77);
971  t_ref=0.25;
972  fp=c.fp(t_ref);
973  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
974  norm.normalize();
975  pt=c.f(t_ref)+dist_ref*norm;
976 
977  t_guess=t_ref;
978  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
979  TEST_ASSERT(tol.approximately_equal(t, t_ref));
980  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
981 
982  t_guess=t_ref+static_cast<data_type>(0.2);
983  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
984  TEST_ASSERT(tol.approximately_equal(t, t_ref));
985  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
986 
987 // Newton's method does not converge.
988 // t_guess=t_ref-static_cast<data_type>(0.2);
989 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
990 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
991 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
992 
993 // Newton's method does not converge.
994 // t_guess=0;
995 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
996 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
997 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
998 
999 // Newton's method does not converge.
1000 // t_guess=1;
1001 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1002 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1003 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1004 
1006  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1007  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1008 
1009  // test point near and outside curve
1010  dist_ref=static_cast<data_type>(0.1);
1011  t_ref=static_cast<data_type>(0.7);
1012  fp=c.fp(t_ref);
1013  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1014  norm.normalize();
1015  pt=c.f(t_ref)+dist_ref*norm;
1016 
1017  t_guess=t_ref;
1018  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1019  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1020  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1021 
1022  t_guess=t_ref+static_cast<data_type>(0.2);
1023  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1024  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1025  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1026 
1027 // Newton's method does not converge.
1028 // t_guess=t_ref-static_cast<data_type>(0.2);
1029 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1030 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1031 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1032 
1033  t_guess=0;
1034  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1035  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1036  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1037 
1038  t_guess=1;
1039  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1040  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1041  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1042 
1044  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1045  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1046 
1047  // test point far and outside curve
1048  dist_ref=3;
1049  t_ref=static_cast<data_type>(0.7);
1050  fp=c.fp(t_ref);
1051  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1052  norm.normalize();
1053  pt=c.f(t_ref)+dist_ref*norm;
1054 
1055  t_guess=t_ref;
1056  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1057  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1058  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1059 
1060 // Newton's method does not converge.
1061 // t_guess=t_ref+static_cast<data_type>(0.2);
1062 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1063 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1064 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1065 
1066 // Newton's method does not converge.
1067 // t_guess=t_ref-static_cast<data_type>(0.2);
1068 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1069 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1070 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1071 
1072 // Newton's method does not converge.
1073 // t_guess=0;
1074 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1075 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1076 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1077 
1078 // Newton's method does not converge.
1079 // t_guess=1;
1080 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1081 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1082 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1083 
1085  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1086  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1087 
1088  // test point near end of curve
1089  dist_ref=static_cast<data_type>(0.1);
1090  t_ref=static_cast<data_type>(0.999);
1091  fp=c.fp(t_ref);
1092  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1093  norm.normalize();
1094  pt=c.f(t_ref)+dist_ref*norm;
1095 
1096  t_guess=t_ref;
1097  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1098  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1099  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1100 
1101  t_guess=t_ref+(1-t_ref)/2;
1102  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1103  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1104  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1105 
1106 // Newton's method does not converge.
1107 // t_guess=t_ref-static_cast<data_type>(0.2);
1108 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1109 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1110 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1111 
1112  t_guess=0;
1113  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1114  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1115  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1116 
1117  t_guess=1;
1118  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1119  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1120  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1121 
1123  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1124  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1125 
1126  // test point near end of and outside curve
1127  dist_ref=static_cast<data_type>(0.1);
1128  t_ref=static_cast<data_type>(0.999);
1129  fp=c.fp(t_ref);
1130  norm << -fp.z(), fp.z(), fp.x()-fp.y();
1131  norm.normalize();
1132  pt=c.f(t_ref)+dist_ref*norm;
1133 
1134  t_guess=t_ref;
1135  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1136  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1137  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1138 
1139  t_guess=t_ref+(1-t_ref)/2;
1140  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1141  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1142  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1143 
1144 // Newton's method does not converge.
1145 // t_guess=t_ref-static_cast<data_type>(0.2);
1146 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1147 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1148 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1149 
1150  t_guess=0;
1151  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1152  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1153  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1154 
1155  t_guess=1;
1156  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1157  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1158  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1159 
1161  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1162  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1163 
1164  // test point near start of curve
1165  dist_ref=static_cast<data_type>(0.1);
1166  t_ref=static_cast<data_type>(0.001);
1167  fp=c.fp(t_ref);
1168  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1169  norm.normalize();
1170  pt=c.f(t_ref)+dist_ref*norm;
1171 
1172  t_guess=t_ref;
1173  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1174  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1175  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1176 
1177 // Newton's method does not converge.
1178 // t_guess=t_ref+static_cast<data_type>(0.2);
1179 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1180 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1181 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1182 
1183  t_guess=t_ref-t_ref/2;
1184  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1185  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1186  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1187 
1188  t_guess=0;
1189  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1190  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1191  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1192 
1193  t_guess=1;
1194  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1195  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1196  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1197 
1199  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1200  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1201 
1202  // test point near start of and outside curve
1203  dist_ref=static_cast<data_type>(0.1);
1204  t_ref=static_cast<data_type>(0.001);
1205  fp=c.fp(t_ref);
1206  norm << -fp.z(), fp.z(), fp.x()-fp.y();
1207  norm.normalize();
1208  pt=c.f(t_ref)+dist_ref*norm;
1209 
1210  t_guess=t_ref;
1211  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1212  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1213  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1214 
1215 // Newton's method does not converge.
1216 // t_guess=t_ref+static_cast<data_type>(0.2);
1217 // dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1218 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1219 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1220 
1221  t_guess=t_ref-t_ref/2;
1222  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1223  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1224  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1225 
1226  t_guess=0;
1227  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1228  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1229  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1230 
1231  t_guess=1;
1232  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1233  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1234  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1235 
1237  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1238  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1239 
1240  // test point near start of and far outside curve
1241  dist_ref=3;
1242  t_ref=static_cast<data_type>(0.001);
1243  fp=c.fp(t_ref);
1244  norm << -fp.z(), fp.z(), fp.x()-fp.y();
1245  norm.normalize();
1246  pt=c.f(t_ref)+dist_ref*norm;
1247 
1248  t_guess=t_ref;
1249  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1250  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1251  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1252 
1253  t_guess=t_ref+static_cast<data_type>(0.2);
1254  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1255  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1256  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1257 
1258  t_guess=t_ref-t_ref/2;
1259  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1260  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1261  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1262 
1263  t_guess=0;
1264  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1265  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1266  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1267 
1268  t_guess=1;
1269  dist=eli::geom::intersect::minimum_distance(t, c, pt, t_guess);
1270  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1271  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1272 
1274  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1275  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1276 // if (typeid(data_type)==typeid(double))
1277 // {
1278 // std::cout << "c_f(t_ref)=" << c.f(t_ref) << "\tpt=" << pt << std::endl;
1279 // std::cout << "dist=" << dist << "\tdist_ref=" << dist_ref << "\tt=" << t << "\tt_ref=" << t_ref << std::endl;
1280 // std::cout << "dist to end=" << (cntrl_in[0]-pt).norm() << std::endl;
1281 // std::vector<point_type3> vec(2);
1282 // vec[0]=pt;
1283 // vec[1]=c.f(t);
1284 // octave_print(1, vec, c);
1285 // }
1286  }
1287 
1289  {
1290  point_type3 cntrl_in[4];
1291 
1292  // set control points
1293  cntrl_in[0] <<-1, 2, 1;
1294  cntrl_in[1] << 0, 1, 0;
1295  cntrl_in[2] << 3, 0, 1;
1296  cntrl_in[3] << 4, 1, 2;
1297 
1298  piecewise_curve_type3 pwc, pwcsave;
1299  curve_type3 c(3);
1300  point_type3 pt, fp, norm;
1301  data_type dist, t, dist_ref, t_ref, t_guess, t_split;
1302  typename piecewise_curve_type3::error_code err;
1303 
1304  // set control points
1305  for (index_type2 i=0; i<4; ++i)
1306  {
1307  c.set_control_point(cntrl_in[i], i);
1308  }
1309 
1310  err=pwc.push_back(c);
1311  TEST_ASSERT(err==piecewise_curve_type3::NO_ERRORS);
1312 
1313  pwcsave=pwc;
1314 
1315  // test point near curve
1316  dist_ref=static_cast<data_type>(0.1);
1317  t_ref=0.25;
1318  fp=pwc.fp(t_ref);
1319  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1320  norm.normalize();
1321  pt=pwc.f(t_ref)+dist_ref*norm;
1322 
1323  t_guess=t_ref;
1324  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1325  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1326  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1327 
1328  t_guess=t_ref+static_cast<data_type>(0.2);
1329  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1330  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1331  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1332 
1333  t_guess=t_ref-static_cast<data_type>(0.2);
1334  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1335  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1336  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1337 
1338  t_guess=0;
1339  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1340  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1341  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1342 
1343 // Case fails because Newton's method seeks local maximum.
1344 // t_guess=1;
1345 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1346 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1347 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1348 
1349  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1350  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1351  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1352 
1353  t_split=t_ref;
1354  pwc.split(t_split);
1355 
1356  t_guess=t_ref;
1357  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1358  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1359  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1360 
1361  t_guess=t_ref+static_cast<data_type>(0.2);
1362  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1363  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1364  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1365 
1366  t_guess=t_ref-static_cast<data_type>(0.2);
1367  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1368  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1369  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1370 
1371  t_guess=t_split;
1372  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1373  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1374  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1375 
1376  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1377  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1378  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1379  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1380 
1381  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1382  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1383  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1384  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1385 
1386  t_guess=0;
1387  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1388  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1389  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1390 
1391 // Case fails because Newton's method seeks local maximum.
1392 // t_guess=1;
1393 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1394 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1395 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1396 
1397  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1398  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1399  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1400 
1401  t_split=t_ref-static_cast<data_type>(0.05);
1402  pwc=pwcsave;
1403  pwc.split(t_split);
1404 
1405  t_guess=t_ref;
1406  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1407  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1408  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1409 
1410  t_guess=t_ref+static_cast<data_type>(0.2);
1411  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1412  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1413  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1414 
1415  t_guess=t_ref-static_cast<data_type>(0.2);
1416  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1417  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1418  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1419 
1420  t_guess=t_split;
1421  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1422  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1423  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1424 
1425  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1426  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1427  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1428  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1429 
1430  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1431  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1432  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1433  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1434 
1435  t_guess=0;
1436  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1437  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1438  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1439 
1440 // Case fails because Newton's method seeks local maximum.
1441 // t_guess=1;
1442 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1443 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1444 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1445 
1446  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1447  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1448  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1449 
1450  t_split=t_ref+static_cast<data_type>(0.05);
1451  pwc=pwcsave;
1452  pwc.split(t_split);
1453 
1454  t_guess=t_ref;
1455  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1456  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1457  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1458 
1459  t_guess=t_ref+static_cast<data_type>(0.2);
1460  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1461  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1462  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1463 
1464  t_guess=t_ref-static_cast<data_type>(0.2);
1465  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1466  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1467  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1468 
1469  t_guess=t_split;
1470  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1471  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1472  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1473 
1474  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1475  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1476  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1477  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1478 
1479  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1480  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1481  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1482  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1483 
1484  t_guess=0;
1485  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1486  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1487  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1488 
1489 // Case fails because Newton's method seeks local maximum.
1490 // t_guess=1;
1491 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1492 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1493 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1494 
1495  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1496  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1497  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1498 
1499  pwcsave=pwc;
1500 
1501  pwc.split(static_cast<data_type>(0.1));
1502  pwc.split(static_cast<data_type>(0.2));
1503  pwc.split(static_cast<data_type>(0.3));
1504  pwc.split(static_cast<data_type>(0.4));
1505  pwc.split(static_cast<data_type>(0.5));
1506  pwc.split(static_cast<data_type>(0.6));
1507  pwc.split(static_cast<data_type>(0.7));
1508  pwc.split(static_cast<data_type>(0.8));
1509  pwc.split(static_cast<data_type>(0.9));
1510 
1511  t_guess=t_ref;
1512  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1513  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1514  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1515 
1516  t_guess=t_ref+static_cast<data_type>(0.2);
1517  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1518  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1519  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1520 
1521  t_guess=t_ref-static_cast<data_type>(0.2);
1522  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1523  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1524  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1525 
1526  t_guess=0;
1527  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1528  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1529  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1530 
1531 // Case fails because Newton's method seeks local maximum.
1532 // t_guess=1;
1533 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1534 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1535 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1536 
1537  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1538  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1539  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1540  }
1541 
1543  {
1544  point_type3 cntrl_in[4];
1545 
1546  // set control points
1547  cntrl_in[0] <<-1, 2, 1;
1548  cntrl_in[1] << 0, 1, 0;
1549  cntrl_in[2] << 3, 0, 1;
1550  cntrl_in[3] << 4, 1, 2;
1551 
1552  piecewise_curve_type3 pwc, pwcsave;
1553  curve_type3 c(3);
1554  point_type3 pt, fp, norm;
1555  data_type dist, t, dist_ref, t_ref, t_guess, t_split, t0;
1556  typename piecewise_curve_type3::error_code err;
1557 
1558  // set control points
1559  for (index_type2 i=0; i<4; ++i)
1560  {
1561  c.set_control_point(cntrl_in[i], i);
1562  }
1563 
1564  err=pwc.push_back(c);
1565  TEST_ASSERT(err==piecewise_curve_type3::NO_ERRORS);
1566 
1567  // pwc.parameter_report();
1568 
1569  t0=static_cast<data_type>(1.6);
1570  pwc.set_t0(t0);
1571 
1572  // pwc.parameter_report();
1573 
1574  pwcsave=pwc;
1575 
1576  // test point near curve
1577  dist_ref=static_cast<data_type>(0.1);
1578  t_ref=static_cast<data_type>(0.25)+t0;
1579  fp=pwc.fp(t_ref);
1580  norm << fp.z(), -fp.z(), -fp.x()+fp.y();
1581  norm.normalize();
1582  pt=pwc.f(t_ref)+dist_ref*norm;
1583 
1584  t_guess=t_ref;
1585  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1586  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1587  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1588 
1589  t_guess=t_ref+static_cast<data_type>(0.2);
1590  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1591  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1592  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1593 
1594  t_guess=t_ref-static_cast<data_type>(0.2);
1595  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1596  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1597  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1598 
1599  t_guess=0+t0;
1600  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1601  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1602  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1603 
1604 // Case fails because Newton's method seeks local maximum.
1605 // t_guess=1+t0;
1606 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1607 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1608 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1609 
1610  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1611  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1612  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1613 
1614  t_split=t_ref;
1615  pwc.split(t_split);
1616 
1617  t_guess=t_ref;
1618  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1619  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1620  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1621 
1622  t_guess=t_ref+static_cast<data_type>(0.2);
1623  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1624  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1625  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1626 
1627  t_guess=t_ref-static_cast<data_type>(0.2);
1628  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1629  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1630  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1631 
1632  t_guess=t_split;
1633  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1634  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1635  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1636 
1637  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1638  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1639  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1640  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1641 
1642  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1643  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1644  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1645  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1646 
1647  t_guess=0+t0;
1648  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1649  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1650  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1651 
1652 // Case fails because Newton's method seeks local maximum.
1653 // t_guess=1+t0;
1654 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1655 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1656 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1657 
1658  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1659  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1660  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1661 
1662  t_split=t_ref-static_cast<data_type>(0.05);
1663  pwc=pwcsave;
1664  pwc.split(t_split);
1665 
1666  t_guess=t_ref;
1667  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1668  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1669  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1670 
1671  t_guess=t_ref+static_cast<data_type>(0.2);
1672  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1673  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1674  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1675 
1676  t_guess=t_ref-static_cast<data_type>(0.2);
1677  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1678  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1679  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1680 
1681  t_guess=t_split;
1682  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1683  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1684  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1685 
1686  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1687  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1688  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1689  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1690 
1691  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1692  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1693  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1694  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1695 
1696  t_guess=0+t0;
1697  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1698  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1699  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1700 
1701 // Case fails because Newton's method seeks local maximum.
1702 // t_guess=1+t0;
1703 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1704 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1705 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1706 
1707  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1708  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1709  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1710 
1711  t_split=t_ref+static_cast<data_type>(0.05);
1712  pwc=pwcsave;
1713  pwc.split(t_split);
1714 
1715  t_guess=t_ref;
1716  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1717  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1718  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1719 
1720  t_guess=t_ref+static_cast<data_type>(0.2);
1721  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1722  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1723  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1724 
1725  t_guess=t_ref-static_cast<data_type>(0.2);
1726  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1727  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1728  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1729 
1730  t_guess=t_split;
1731  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1732  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1733  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1734 
1735  t_guess=t_split+std::numeric_limits<data_type>::epsilon();
1736  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1737  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1738  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1739 
1740  t_guess=t_split-std::numeric_limits<data_type>::epsilon();
1741  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1742  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1743  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1744 
1745  t_guess=0+t0;
1746  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1747  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1748  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1749 
1750 // Case fails because Newton's method seeks local maximum.
1751 // t_guess=1+t0;
1752 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1753 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1754 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1755 
1756  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1757  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1758  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1759 
1760  pwcsave=pwc;
1761 
1762  pwc.split(static_cast<data_type>(0.1)+t0);
1763  pwc.split(static_cast<data_type>(0.2)+t0);
1764  pwc.split(static_cast<data_type>(0.3)+t0);
1765  pwc.split(static_cast<data_type>(0.4)+t0);
1766  pwc.split(static_cast<data_type>(0.5)+t0);
1767  pwc.split(static_cast<data_type>(0.6)+t0);
1768  pwc.split(static_cast<data_type>(0.7)+t0);
1769  pwc.split(static_cast<data_type>(0.8)+t0);
1770  pwc.split(static_cast<data_type>(0.9)+t0);
1771 
1772  t_guess=t_ref;
1773  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1774  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1775  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1776 
1777  t_guess=t_ref+static_cast<data_type>(0.2);
1778  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1779  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1780  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1781 
1782  t_guess=t_ref-static_cast<data_type>(0.2);
1783  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1784  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1785  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1786 
1787  t_guess=0+t0;
1788  dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1789  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1790  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1791 
1792 // Case fails because Newton's method seeks local maximum.
1793 // t_guess=1+t0;
1794 // dist=eli::geom::intersect::minimum_distance(t, pwc, pt, t_guess);
1795 // TEST_ASSERT(tol.approximately_equal(t, t_ref));
1796 // TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1797 
1798  dist=eli::geom::intersect::minimum_distance(t, pwc, pt);
1799  TEST_ASSERT(tol.approximately_equal(t, t_ref));
1800  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1801 
1802  }
1803 };
1804 
1805 #endif
1806 
void AddTests(const long double &)
Definition: minimum_distance_curve_test_suite.hpp:64
~minimum_distance_curve_test_suite()
Definition: minimum_distance_curve_test_suite.hpp:80
curve::piecewise< curve1__, data1__, dim1__, tol1__ >::data_type minimum_distance(typename curve::piecewise< curve1__, data1__, dim1__, tol1__ >::data_type &t, const curve::piecewise< curve1__, data1__, dim1__, tol1__ > &pc, const typename curve::piecewise< curve1__, data1__, dim1__, tol1__ >::point_type &pt)
minimum_distance_curve_test_suite()
Definition: minimum_distance_curve_test_suite.hpp:76
curve_type2::tolerance_type tolerance_type
Definition: minimum_distance_curve_test_suite.hpp:39
Eigen::Matrix< data_type, 1, dim__ > point_type
Definition: bezier.hpp:114
Definition: piecewise.hpp:281
point_type f(const data_type &t) const
Definition: bezier.hpp:324
error_code push_back(const curve_type &curve, const data_type &dt=1.0)
Definition: piecewise.hpp:688
tol__ tolerance_type
Definition: bezier.hpp:118
void AddTests(const double &)
Definition: minimum_distance_curve_test_suite.hpp:54
Definition: minimum_distance_curve_test_suite.hpp:25
void point_piecewise_01_smooth_3d_test()
Definition: minimum_distance_curve_test_suite.hpp:1288
Definition: piecewise.hpp:244
void point_smooth_2d_test()
Definition: minimum_distance_curve_test_suite.hpp:181
data__ data_type
Definition: minimum_distance_curve_test_suite.hpp:28
curve__< data__, dim__, tol__ > curve_type
Definition: piecewise.hpp:270
void point_closed_2d_test()
Definition: minimum_distance_curve_test_suite.hpp:308
error_code
Definition: piecewise.hpp:279
eli::geom::curve::bezier< data_type, 2 > curve_type2
Definition: minimum_distance_curve_test_suite.hpp:30
void point_smooth_3d_test()
Definition: minimum_distance_curve_test_suite.hpp:438
void point_piecewise_trange_smooth_3d_test()
Definition: minimum_distance_curve_test_suite.hpp:1542
void AddTests(const float &)
Definition: minimum_distance_curve_test_suite.hpp:44
void octave_print(int figno, const std::vector< point_type2 > &pts, const curve_type2 &c) const
Definition: minimum_distance_curve_test_suite.hpp:85
curve_type2::point_type point_type2
Definition: minimum_distance_curve_test_suite.hpp:31
point_type fp(const data_type &t) const
Definition: piecewise.hpp:1748
void set_control_point(const control_point_type &cp, const index_type &i)
Definition: bezier.hpp:201
eli::geom::curve::piecewise< eli::geom::curve::bezier, data__, 3 > piecewise_curve_type3
Definition: minimum_distance_curve_test_suite.hpp:34
curve_type3::point_type point_type3
Definition: minimum_distance_curve_test_suite.hpp:36
point_type f(const data_type &t) const
Definition: piecewise.hpp:1732
curve_type3::index_type index_type3
Definition: minimum_distance_curve_test_suite.hpp:37
void set_t0(const data_type &t0_in)
Definition: piecewise.hpp:340
error_code split(const data_type &t)
Definition: piecewise.hpp:1055
point_type fp(const data_type &t) const
Definition: bezier.hpp:344
Definition: bezier.hpp:109
curve_type2::index_type index_type2
Definition: minimum_distance_curve_test_suite.hpp:32
piecewise_curve_type3::curve_type curve_type3
Definition: minimum_distance_curve_test_suite.hpp:35
void point_closed_3d_test()
Definition: minimum_distance_curve_test_suite.hpp:864
tolerance_type tol
Definition: minimum_distance_curve_test_suite.hpp:41
point_type::Index index_type
Definition: bezier.hpp:116
void octave_print(int figno, const std::vector< point_type3 > &pts, const curve_type3 &c) const
Definition: minimum_distance_curve_test_suite.hpp:128