Code-Eli  0.3.6
minimum_distance_surface_test_suite.hpp
Go to the documentation of this file.
1 /*********************************************************************************
2 * Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * David D. Marshall - initial code and implementation
11 ********************************************************************************/
12 
13 #ifndef minimum_distance_surface_test_suite_hpp
14 #define minimum_distance_surface_test_suite_hpp
15 
16 #include <cmath> // cos(), sin()
17 
18 #include <typeinfo> // typeid
19 
23 
24 template<typename data__>
25 class minimum_distance_surface_test_suite : public Test::Suite
26 {
27  private:
28  typedef data__ data_type;
29 
32  typedef typename surface_type::point_type point_type;
33  typedef typename surface_type::index_type index_type;
34  typedef typename surface_type::tolerance_type tolerance_type;
35 
36  tolerance_type tol;
37 
38  protected:
39  void AddTests(const float &)
40  {
41  // add the tests
46  }
47  void AddTests(const double &)
48  {
49  // add the tests
54  }
55  void AddTests(const long double &)
56  {
57  // add the tests
62  }
63 
64  public:
66  {
67  AddTests(data__());
68  }
70  {
71  }
72 
73  private:
74  void octave_print(int figno, const std::vector<point_type> &pts, const surface_type &s) const
75  {
76  size_t i, j;
77 
78  std::cout << "figure(" << figno << ");" << std::endl;
79  std::cout << "xpts=[" << pts[0].x();
80  for (i=1; i<pts.size(); ++i)
81  std::cout << ", " << pts[i].x();
82  std::cout << "];" << std::endl;
83  std::cout << "ypts=[" << pts[0].y();
84  for (i=1; i<pts.size(); ++i)
85  std::cout << ", " << pts[i].y();
86  std::cout << "];" << std::endl;
87  std::cout << "zpts=[" << pts[0].z();
88  for (i=1; i<pts.size(); ++i)
89  std::cout << ", " << pts[i].z();
90  std::cout << "];" << std::endl;
91 
92  // initialize the u & v parameters
93  std::vector<data__> u(51), v(51);
94  for (i=0; i<u.size(); ++i)
95  {
96  u[i]=static_cast<data__>(i)/(u.size()-1);
97  }
98  for (j=0; j<v.size(); ++j)
99  {
100  v[j]=static_cast<data__>(j)/(v.size()-1);
101  }
102 
103  // set the surface points
104  std::cout << "surf_x=[";
105  for (i=0; i<u.size(); ++i)
106  {
107  std::cout << s.f(u[i], v[0]).x();
108  for (j=1; j<(v.size()-1); ++j)
109  {
110  std::cout << ", " << s.f(u[i], v[j]).x();
111  }
112  j=v.size()-1;
113  std::cout << ", " << s.f(u[i], v[j]).x();
114  if (i<(u.size()-1))
115  std::cout << "; " << std::endl;
116  }
117  std::cout << "];" << std::endl;
118 
119  std::cout << "surf_y=[";
120  for (i=0; i<u.size(); ++i)
121  {
122  std::cout << s.f(u[i], v[0]).y();
123  for (j=1; j<(v.size()-1); ++j)
124  {
125  std::cout << ", " << s.f(u[i], v[j]).y();
126  }
127  j=v.size()-1;
128  std::cout << ", " << s.f(u[i], v[j]).y();
129  if (i<(u.size()-1))
130  std::cout << "; " << std::endl;
131  }
132  std::cout << "];" << std::endl;
133 
134  std::cout << "surf_z=[";
135  for (i=0; i<u.size(); ++i)
136  {
137  std::cout << s.f(u[i], v[0]).z();
138  for (j=1; j<(v.size()-1); ++j)
139  {
140  std::cout << ", " << s.f(u[i], v[j]).z();
141  }
142  j=v.size()-1;
143  std::cout << ", " << s.f(u[i], v[j]).z();
144  if (i<(u.size()-1))
145  std::cout << "; " << std::endl;
146  }
147  std::cout << "];" << std::endl;
148 
149  std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
150  std::cout << "mesh(surf_x, surf_y, surf_z, zeros(size(surf_z)), 'EdgeColor', [0 0 0]);" << std::endl;
151  std::cout << "hold on;" << std::endl;
152  std::cout << "plot3(xpts, ypts, zpts, 'or', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'r');" << std::endl;
153  std::cout << "hold off;" << std::endl;
154  std::cout << "axis equal" << std::endl;
155 
156  std::cout << "figure(" << figno+1 << ");" << std::endl;
157  std::cout << "u=[" << u[0];
158  for (i=1; i<u.size(); ++i)
159  std::cout << ", " << u[i];
160  std::cout << "];" << std::endl;
161  std::cout << "v=[" << v[0];
162  for (i=1; i<v.size(); ++i)
163  std::cout << ", " << v[i];
164  std::cout << "];" << std::endl;
165  std::cout << "g_u=[";
166  for (i=0; i<u.size(); ++i)
167  {
168  j=0;
169  std::cout << (s.f(u[i], v[j])-pts[0]).dot(s.f_u(u[i], v[j]));
170  for (j=1; j<(v.size()-1); ++j)
171  {
172  std::cout << ", " << (s.f(u[i], v[j])-pts[0]).dot(s.f_u(u[i], v[j]));
173  }
174  j=v.size()-1;
175  std::cout << ", " << (s.f(u[i], v[j])-pts[0]).dot(s.f_u(u[i], v[j]));
176  if (i<(u.size()-1))
177  std::cout << "; " << std::endl;
178  }
179  std::cout << "];" << std::endl;
180  std::cout << "g_v=[";
181  for (i=0; i<u.size(); ++i)
182  {
183  j=0;
184  std::cout << (s.f(u[i], v[j])-pts[0]).dot(s.f_v(u[i], v[j]));
185  for (j=1; j<(v.size()-1); ++j)
186  {
187  std::cout << ", " << (s.f(u[i], v[j])-pts[0]).dot(s.f_v(u[i], v[j]));
188  }
189  j=v.size()-1;
190  std::cout << ", " << (s.f(u[i], v[j])-pts[0]).dot(s.f_v(u[i], v[j]));
191  if (i<(u.size()-1))
192  std::cout << "; " << std::endl;
193  }
194  std::cout << "];" << std::endl;
195 
196  std::cout << "setenv('GNUTERM', 'x11');" << std::endl;
197  std::cout << "mesh(u, v, g_u, zeros(length(u), length(v)), 'EdgeColor', [0 0 0]);" << std::endl;
198  std::cout << "hold on;" << std::endl;
199  std::cout << "mesh(u, v, g_v, zeros(length(u), length(v)), 'EdgeColor', [0 0 0]);" << std::endl;
200  std::cout << "surf(u, v, zeros(length(u), length(v)));" << std::endl;
201  std::cout << "hold off;" << std::endl;
202  }
203 
205  {
206  const index_type n(3), m(3);
207  surface_type s(n, m);
208  point_type cp[3+1][3+1], pt_out;
209  point_type pt, norm, u_contra, v_contra;
210  data_type dist, u, v, dist_ref, u_ref, v_ref;
211  data_type u_off(static_cast<data_type>(0.2)), v_off(static_cast<data_type>(0.2));
212  index_type i, j;
213 
214  // create surface with specified control points
215  cp[0][0] << -15, 0, 15;
216  cp[1][0] << -5, 5, 15;
217  cp[2][0] << 5, 5, 15;
218  cp[3][0] << 15, 0, 15;
219  cp[0][1] << -15, 5, 5;
220  cp[1][1] << -5, 5, 5;
221  cp[2][1] << 5, 5, 5;
222  cp[3][1] << 15, 5, 5;
223  cp[0][2] << -15, 5, -5;
224  cp[1][2] << -5, 5, -5;
225  cp[2][2] << 5, 5, -5;
226  cp[3][2] << 15, 5, -5;
227  cp[0][3] << -15, 0, -15;
228  cp[1][3] << -5, 5, -15;
229  cp[2][3] << 5, 5, -15;
230  cp[3][3] << 15, 0, -15;
231 
232  // create surface with specified dimensions and set control points
233  for (i=0; i<=n; ++i)
234  {
235  for (j=0; j<=m; ++j)
236  {
237  s.set_control_point(cp[i][j], i, j);
238  }
239  }
240  TEST_ASSERT(s.open_u());
241  TEST_ASSERT(s.open_v());
242 
243  // test point on surface
244  dist_ref=0;
245  u_ref=0.25;
246  v_ref=0.25;
247  norm=s.normal(u_ref, v_ref);
248  pt=s.f(u_ref, v_ref)+dist_ref*norm;
249  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
250  TEST_ASSERT(tol.approximately_equal(u, u_ref));
251  TEST_ASSERT(tol.approximately_equal(v, v_ref));
252  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
253 
254  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
255  TEST_ASSERT(tol.approximately_equal(u, u_ref));
256  TEST_ASSERT(tol.approximately_equal(v, v_ref));
257  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
258 
259  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
260  TEST_ASSERT(tol.approximately_equal(u, u_ref));
261  TEST_ASSERT(tol.approximately_equal(v, v_ref));
262  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
263 
264  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
265  TEST_ASSERT(tol.approximately_equal(u, u_ref));
266  TEST_ASSERT(tol.approximately_equal(v, v_ref));
267  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
268 
269  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
270  TEST_ASSERT(tol.approximately_equal(u, u_ref));
271  TEST_ASSERT(tol.approximately_equal(v, v_ref));
272  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
273 
274  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
275  TEST_ASSERT(tol.approximately_equal(u, u_ref));
276  TEST_ASSERT(tol.approximately_equal(v, v_ref));
277  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
278 
279  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
280  TEST_ASSERT(tol.approximately_equal(u, u_ref));
281  TEST_ASSERT(tol.approximately_equal(v, v_ref));
282  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
283 
284  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
285  TEST_ASSERT(tol.approximately_equal(u, u_ref));
286  TEST_ASSERT(tol.approximately_equal(v, v_ref));
287  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
288 
289  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
290  TEST_ASSERT(tol.approximately_equal(u, u_ref));
291  TEST_ASSERT(tol.approximately_equal(v, v_ref));
292  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
293 
294  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
295  TEST_ASSERT(tol.approximately_equal(u, u_ref));
296  TEST_ASSERT(tol.approximately_equal(v, v_ref));
297  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
298 
299  // test point very near surface
300  dist_ref=static_cast<data_type>(0.01);
301  u_ref=0.25;
302  v_ref=0.25;
303  norm=s.normal(u_ref, v_ref);
304  pt=s.f(u_ref, v_ref)+dist_ref*norm;
305  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
306  TEST_ASSERT(tol.approximately_equal(u, u_ref));
307  TEST_ASSERT(tol.approximately_equal(v, v_ref));
308  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
309 
310  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
311  TEST_ASSERT(tol.approximately_equal(u, u_ref));
312  TEST_ASSERT(tol.approximately_equal(v, v_ref));
313  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
314 
315  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
316  TEST_ASSERT(tol.approximately_equal(u, u_ref));
317  TEST_ASSERT(tol.approximately_equal(v, v_ref));
318  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
319 
320  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
321  TEST_ASSERT(tol.approximately_equal(u, u_ref));
322  TEST_ASSERT(tol.approximately_equal(v, v_ref));
323  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
324 
325  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
326  TEST_ASSERT(tol.approximately_equal(u, u_ref));
327  TEST_ASSERT(tol.approximately_equal(v, v_ref));
328  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
329 
330  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
331  TEST_ASSERT(tol.approximately_equal(u, u_ref));
332  TEST_ASSERT(tol.approximately_equal(v, v_ref));
333  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
334 
335  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
336  TEST_ASSERT(tol.approximately_equal(u, u_ref));
337  TEST_ASSERT(tol.approximately_equal(v, v_ref));
338  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
339 
340  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
341  TEST_ASSERT(tol.approximately_equal(u, u_ref));
342  TEST_ASSERT(tol.approximately_equal(v, v_ref));
343  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
344 
345  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
346  TEST_ASSERT(tol.approximately_equal(u, u_ref));
347  TEST_ASSERT(tol.approximately_equal(v, v_ref));
348  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
349 
350  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
351  TEST_ASSERT(tol.approximately_equal(u, u_ref));
352  TEST_ASSERT(tol.approximately_equal(v, v_ref));
353  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
354 
355  // test point near surface
356  dist_ref=static_cast<data_type>(0.1);
357  u_ref=0.25;
358  v_ref=0.25;
359  norm=s.normal(u_ref, v_ref);
360  pt=s.f(u_ref, v_ref)+dist_ref*norm;
361  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
362  TEST_ASSERT(tol.approximately_equal(u, u_ref));
363  TEST_ASSERT(tol.approximately_equal(v, v_ref));
364  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
365 
366  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
367  TEST_ASSERT(tol.approximately_equal(u, u_ref));
368  TEST_ASSERT(tol.approximately_equal(v, v_ref));
369  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
370 
371  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
372  TEST_ASSERT(tol.approximately_equal(u, u_ref));
373  TEST_ASSERT(tol.approximately_equal(v, v_ref));
374  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
375 
376  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
377  TEST_ASSERT(tol.approximately_equal(u, u_ref));
378  TEST_ASSERT(tol.approximately_equal(v, v_ref));
379  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
380 
381  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
382  TEST_ASSERT(tol.approximately_equal(u, u_ref));
383  TEST_ASSERT(tol.approximately_equal(v, v_ref));
384  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
385 
386  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
387  TEST_ASSERT(tol.approximately_equal(u, u_ref));
388  TEST_ASSERT(tol.approximately_equal(v, v_ref));
389  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
390 
391  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
392  TEST_ASSERT(tol.approximately_equal(u, u_ref));
393  TEST_ASSERT(tol.approximately_equal(v, v_ref));
394  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
395 
396  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
397  TEST_ASSERT(tol.approximately_equal(u, u_ref));
398  TEST_ASSERT(tol.approximately_equal(v, v_ref));
399  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
400 
401  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
402  TEST_ASSERT(tol.approximately_equal(u, u_ref));
403  TEST_ASSERT(tol.approximately_equal(v, v_ref));
404  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
405 
406  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
407  TEST_ASSERT(tol.approximately_equal(u, u_ref));
408  TEST_ASSERT(tol.approximately_equal(v, v_ref));
409  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
410 
411  // test point near and on concave side of surface
412  dist_ref=static_cast<data_type>(0.1);
413  u_ref=0.25;
414  v_ref=0.25;
415  norm=-s.normal(u_ref, v_ref);
416  pt=s.f(u_ref, v_ref)+dist_ref*norm;
417  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
418  TEST_ASSERT(tol.approximately_equal(u, u_ref));
419  TEST_ASSERT(tol.approximately_equal(v, v_ref));
420  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
421 
422  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
423  TEST_ASSERT(tol.approximately_equal(u, u_ref));
424  TEST_ASSERT(tol.approximately_equal(v, v_ref));
425  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
426 
427  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
428  TEST_ASSERT(tol.approximately_equal(u, u_ref));
429  TEST_ASSERT(tol.approximately_equal(v, v_ref));
430  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
431 
432  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
433  TEST_ASSERT(tol.approximately_equal(u, u_ref));
434  TEST_ASSERT(tol.approximately_equal(v, v_ref));
435  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
436 
437  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
438  TEST_ASSERT(tol.approximately_equal(u, u_ref));
439  TEST_ASSERT(tol.approximately_equal(v, v_ref));
440  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
441 
442  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
443  TEST_ASSERT(tol.approximately_equal(u, u_ref));
444  TEST_ASSERT(tol.approximately_equal(v, v_ref));
445  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
446 
447  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
448  TEST_ASSERT(tol.approximately_equal(u, u_ref));
449  TEST_ASSERT(tol.approximately_equal(v, v_ref));
450  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
451 
452  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
453  TEST_ASSERT(tol.approximately_equal(u, u_ref));
454  TEST_ASSERT(tol.approximately_equal(v, v_ref));
455  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
456 
457  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
458  TEST_ASSERT(tol.approximately_equal(u, u_ref));
459  TEST_ASSERT(tol.approximately_equal(v, v_ref));
460  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
461 
462  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
463  TEST_ASSERT(tol.approximately_equal(u, u_ref));
464  TEST_ASSERT(tol.approximately_equal(v, v_ref));
465  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
466 
467  // test point far surface
468  dist_ref=static_cast<data_type>(1.1);
469  u_ref=0.25;
470  v_ref=0.25;
471  norm=s.normal(u_ref, v_ref);
472  pt=s.f(u_ref, v_ref)+dist_ref*norm;
473  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
474  TEST_ASSERT(tol.approximately_equal(u, u_ref));
475  TEST_ASSERT(tol.approximately_equal(v, v_ref));
476  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
477 
478  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
479  TEST_ASSERT(tol.approximately_equal(u, u_ref));
480  TEST_ASSERT(tol.approximately_equal(v, v_ref));
481  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
482 
483  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
484  TEST_ASSERT(tol.approximately_equal(u, u_ref));
485  TEST_ASSERT(tol.approximately_equal(v, v_ref));
486  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
487 
488  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
489  TEST_ASSERT(tol.approximately_equal(u, u_ref));
490  TEST_ASSERT(tol.approximately_equal(v, v_ref));
491  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
492 
493  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
494  TEST_ASSERT(tol.approximately_equal(u, u_ref));
495  TEST_ASSERT(tol.approximately_equal(v, v_ref));
496  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
497 
498  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
499  TEST_ASSERT(tol.approximately_equal(u, u_ref));
500  TEST_ASSERT(tol.approximately_equal(v, v_ref));
501  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
502 
503  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
504  TEST_ASSERT(tol.approximately_equal(u, u_ref));
505  TEST_ASSERT(tol.approximately_equal(v, v_ref));
506  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
507 
508  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
509  TEST_ASSERT(tol.approximately_equal(u, u_ref));
510  TEST_ASSERT(tol.approximately_equal(v, v_ref));
511  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
512 
513  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
514  TEST_ASSERT(tol.approximately_equal(u, u_ref));
515  TEST_ASSERT(tol.approximately_equal(v, v_ref));
516  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
517 
518  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
519  TEST_ASSERT(tol.approximately_equal(u, u_ref));
520  TEST_ASSERT(tol.approximately_equal(v, v_ref));
521  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
522 
523  // test point on surface
524  dist_ref=0;
525  u_ref=static_cast<data_type>(0.64);
526  v_ref=static_cast<data_type>(0.32);
527  norm=s.normal(u_ref, v_ref);
528  pt=s.f(u_ref, v_ref)+dist_ref*norm;
529  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
530  TEST_ASSERT(tol.approximately_equal(u, u_ref));
531  TEST_ASSERT(tol.approximately_equal(v, v_ref));
532  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
533 
534  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
535  TEST_ASSERT(tol.approximately_equal(u, u_ref));
536  TEST_ASSERT(tol.approximately_equal(v, v_ref));
537  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
538 
539  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
540  TEST_ASSERT(tol.approximately_equal(u, u_ref));
541  TEST_ASSERT(tol.approximately_equal(v, v_ref));
542  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
543 
544  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
545  TEST_ASSERT(tol.approximately_equal(u, u_ref));
546  TEST_ASSERT(tol.approximately_equal(v, v_ref));
547  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
548 
549  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
550  TEST_ASSERT(tol.approximately_equal(u, u_ref));
551  TEST_ASSERT(tol.approximately_equal(v, v_ref));
552  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
553 
554  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
555  TEST_ASSERT(tol.approximately_equal(u, u_ref));
556  TEST_ASSERT(tol.approximately_equal(v, v_ref));
557  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
558 
559  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
560  TEST_ASSERT(tol.approximately_equal(u, u_ref));
561  TEST_ASSERT(tol.approximately_equal(v, v_ref));
562  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
563 
564  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
565  TEST_ASSERT(tol.approximately_equal(u, u_ref));
566  TEST_ASSERT(tol.approximately_equal(v, v_ref));
567  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
568 
569  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
570  TEST_ASSERT(tol.approximately_equal(u, u_ref));
571  TEST_ASSERT(tol.approximately_equal(v, v_ref));
572  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
573 
574  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
575  TEST_ASSERT(tol.approximately_equal(u, u_ref));
576  TEST_ASSERT(tol.approximately_equal(v, v_ref));
577  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
578 
579  // test point very near surface
580  dist_ref=static_cast<data_type>(0.01);
581  u_ref=static_cast<data_type>(0.64);
582  v_ref=static_cast<data_type>(0.32);
583  norm=s.normal(u_ref, v_ref);
584  pt=s.f(u_ref, v_ref)+dist_ref*norm;
585  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
586  TEST_ASSERT(tol.approximately_equal(u, u_ref));
587  TEST_ASSERT(tol.approximately_equal(v, v_ref));
588  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
589 
590  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
591  TEST_ASSERT(tol.approximately_equal(u, u_ref));
592  TEST_ASSERT(tol.approximately_equal(v, v_ref));
593  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
594 
595  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
596  TEST_ASSERT(tol.approximately_equal(u, u_ref));
597  TEST_ASSERT(tol.approximately_equal(v, v_ref));
598  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
599 
600  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
601  TEST_ASSERT(tol.approximately_equal(u, u_ref));
602  TEST_ASSERT(tol.approximately_equal(v, v_ref));
603  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
604 
605  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
606  TEST_ASSERT(tol.approximately_equal(u, u_ref));
607  TEST_ASSERT(tol.approximately_equal(v, v_ref));
608  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
609 
610  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
611  TEST_ASSERT(tol.approximately_equal(u, u_ref));
612  TEST_ASSERT(tol.approximately_equal(v, v_ref));
613  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
614 
615  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
616  TEST_ASSERT(tol.approximately_equal(u, u_ref));
617  TEST_ASSERT(tol.approximately_equal(v, v_ref));
618  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
619 
620  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
621  TEST_ASSERT(tol.approximately_equal(u, u_ref));
622  TEST_ASSERT(tol.approximately_equal(v, v_ref));
623  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
624 
625  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
626  TEST_ASSERT(tol.approximately_equal(u, u_ref));
627  TEST_ASSERT(tol.approximately_equal(v, v_ref));
628  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
629 
630  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
631  TEST_ASSERT(tol.approximately_equal(u, u_ref));
632  TEST_ASSERT(tol.approximately_equal(v, v_ref));
633  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
634 
635  // test point near surface
636  dist_ref=static_cast<data_type>(0.1);
637  u_ref=static_cast<data_type>(0.64);
638  v_ref=static_cast<data_type>(0.32);
639  norm=s.normal(u_ref, v_ref);
640  pt=s.f(u_ref, v_ref)+dist_ref*norm;
641  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
642  TEST_ASSERT(tol.approximately_equal(u, u_ref));
643  TEST_ASSERT(tol.approximately_equal(v, v_ref));
644  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
645 
646  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
647  TEST_ASSERT(tol.approximately_equal(u, u_ref));
648  TEST_ASSERT(tol.approximately_equal(v, v_ref));
649  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
650 
651  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
652  TEST_ASSERT(tol.approximately_equal(u, u_ref));
653  TEST_ASSERT(tol.approximately_equal(v, v_ref));
654  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
655 
656  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
657  TEST_ASSERT(tol.approximately_equal(u, u_ref));
658  TEST_ASSERT(tol.approximately_equal(v, v_ref));
659  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
660 
661  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
662  TEST_ASSERT(tol.approximately_equal(u, u_ref));
663  TEST_ASSERT(tol.approximately_equal(v, v_ref));
664  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
665 
666  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
667  TEST_ASSERT(tol.approximately_equal(u, u_ref));
668  TEST_ASSERT(tol.approximately_equal(v, v_ref));
669  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
670 
671  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
672  TEST_ASSERT(tol.approximately_equal(u, u_ref));
673  TEST_ASSERT(tol.approximately_equal(v, v_ref));
674  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
675 
676  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
677  TEST_ASSERT(tol.approximately_equal(u, u_ref));
678  TEST_ASSERT(tol.approximately_equal(v, v_ref));
679  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
680 
681  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
682  TEST_ASSERT(tol.approximately_equal(u, u_ref));
683  TEST_ASSERT(tol.approximately_equal(v, v_ref));
684  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
685 
686  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
687  TEST_ASSERT(tol.approximately_equal(u, u_ref));
688  TEST_ASSERT(tol.approximately_equal(v, v_ref));
689  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
690 
691  // test point near and on concave side of surface
692  dist_ref=static_cast<data_type>(0.1);
693  u_ref=static_cast<data_type>(0.64);
694  v_ref=static_cast<data_type>(0.32);
695  norm=-s.normal(u_ref, v_ref);
696  pt=s.f(u_ref, v_ref)+dist_ref*norm;
697  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
698  TEST_ASSERT(tol.approximately_equal(u, u_ref));
699  TEST_ASSERT(tol.approximately_equal(v, v_ref));
700  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
701 
702  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
703  TEST_ASSERT(tol.approximately_equal(u, u_ref));
704  TEST_ASSERT(tol.approximately_equal(v, v_ref));
705  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
706 
707  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
708  TEST_ASSERT(tol.approximately_equal(u, u_ref));
709  TEST_ASSERT(tol.approximately_equal(v, v_ref));
710  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
711 
712  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
713  TEST_ASSERT(tol.approximately_equal(u, u_ref));
714  TEST_ASSERT(tol.approximately_equal(v, v_ref));
715  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
716 
717  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
718  TEST_ASSERT(tol.approximately_equal(u, u_ref));
719  TEST_ASSERT(tol.approximately_equal(v, v_ref));
720  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
721 
722  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
723  TEST_ASSERT(tol.approximately_equal(u, u_ref));
724  TEST_ASSERT(tol.approximately_equal(v, v_ref));
725  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
726 
727  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
728  TEST_ASSERT(tol.approximately_equal(u, u_ref));
729  TEST_ASSERT(tol.approximately_equal(v, v_ref));
730  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
731 
732  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
733  TEST_ASSERT(tol.approximately_equal(u, u_ref));
734  TEST_ASSERT(tol.approximately_equal(v, v_ref));
735  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
736 
737  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
738  TEST_ASSERT(tol.approximately_equal(u, u_ref));
739  TEST_ASSERT(tol.approximately_equal(v, v_ref));
740  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
741 
742  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
743  TEST_ASSERT(tol.approximately_equal(u, u_ref));
744  TEST_ASSERT(tol.approximately_equal(v, v_ref));
745  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
746 
747  // test point near surface
748  dist_ref=static_cast<data_type>(1.1);
749  u_ref=static_cast<data_type>(0.64);
750  v_ref=static_cast<data_type>(0.32);
751  norm=s.normal(u_ref, v_ref);
752  pt=s.f(u_ref, v_ref)+dist_ref*norm;
753  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
754  TEST_ASSERT(tol.approximately_equal(u, u_ref));
755  TEST_ASSERT(tol.approximately_equal(v, v_ref));
756  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
757 
758  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
759  TEST_ASSERT(tol.approximately_equal(u, u_ref));
760  TEST_ASSERT(tol.approximately_equal(v, v_ref));
761  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
762 
763  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
764  TEST_ASSERT(tol.approximately_equal(u, u_ref));
765  TEST_ASSERT(tol.approximately_equal(v, v_ref));
766  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
767 
768  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
769  TEST_ASSERT(tol.approximately_equal(u, u_ref));
770  TEST_ASSERT(tol.approximately_equal(v, v_ref));
771  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
772 
773  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
774  TEST_ASSERT(tol.approximately_equal(u, u_ref));
775  TEST_ASSERT(tol.approximately_equal(v, v_ref));
776  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
777 
778  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
779  TEST_ASSERT(tol.approximately_equal(u, u_ref));
780  TEST_ASSERT(tol.approximately_equal(v, v_ref));
781  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
782 
783  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
784  TEST_ASSERT(tol.approximately_equal(u, u_ref));
785  TEST_ASSERT(tol.approximately_equal(v, v_ref));
786  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
787 
788  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
789  TEST_ASSERT(tol.approximately_equal(u, u_ref));
790  TEST_ASSERT(tol.approximately_equal(v, v_ref));
791  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
792 
793  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
794  TEST_ASSERT(tol.approximately_equal(u, u_ref));
795  TEST_ASSERT(tol.approximately_equal(v, v_ref));
796  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
797 
798  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
799  TEST_ASSERT(tol.approximately_equal(u, u_ref));
800  TEST_ASSERT(tol.approximately_equal(v, v_ref));
801  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
802 
803  // test point near corner of surface
804  dist_ref=static_cast<data_type>(0.1);
805  u_ref=static_cast<data_type>(0.01);
806  v_ref=static_cast<data_type>(0.01);
807  norm=s.normal(u_ref, v_ref);
808  pt=s.f(u_ref, v_ref)+dist_ref*norm;
809  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
810  TEST_ASSERT(tol.approximately_equal(u, u_ref));
811  TEST_ASSERT(tol.approximately_equal(v, v_ref));
812  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
813 
814  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
815  TEST_ASSERT(tol.approximately_equal(u, u_ref));
816  TEST_ASSERT(tol.approximately_equal(v, v_ref));
817  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
818 
819  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
820  TEST_ASSERT(tol.approximately_equal(u, u_ref));
821  TEST_ASSERT(tol.approximately_equal(v, v_ref));
822  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
823 
824  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref);
825  TEST_ASSERT(tol.approximately_equal(u, u_ref));
826  TEST_ASSERT(tol.approximately_equal(v, v_ref));
827  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
828 
829  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+v_off);
830  TEST_ASSERT(tol.approximately_equal(u, u_ref));
831  TEST_ASSERT(tol.approximately_equal(v, v_ref));
832  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
833 
834  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
835  TEST_ASSERT(tol.approximately_equal(u, u_ref));
836  TEST_ASSERT(tol.approximately_equal(v, v_ref));
837  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
838 
839  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
840  TEST_ASSERT(tol.approximately_equal(u, u_ref));
841  TEST_ASSERT(tol.approximately_equal(v, v_ref));
842  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
843 
844  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
845  TEST_ASSERT(tol.approximately_equal(u, u_ref));
846  TEST_ASSERT(tol.approximately_equal(v, v_ref));
847  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
848 
849  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
850  TEST_ASSERT(tol.approximately_equal(u, u_ref));
851  TEST_ASSERT(tol.approximately_equal(v, v_ref));
852  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
853 
854  // test point near corner of surface
855  dist_ref=static_cast<data_type>(0.1);
856  u_ref=static_cast<data_type>(0.99);
857  v_ref=static_cast<data_type>(0.01);
858  norm=s.normal(u_ref, v_ref);
859  pt=s.f(u_ref, v_ref)+dist_ref*norm;
860  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
861  TEST_ASSERT(tol.approximately_equal(u, u_ref));
862  TEST_ASSERT(tol.approximately_equal(v, v_ref));
863  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
864 
865  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
866  TEST_ASSERT(tol.approximately_equal(u, u_ref));
867  TEST_ASSERT(tol.approximately_equal(v, v_ref));
868  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
869 
870  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+v_off);
871  TEST_ASSERT(tol.approximately_equal(u, u_ref));
872  TEST_ASSERT(tol.approximately_equal(v, v_ref));
873  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
874 
875  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
876  TEST_ASSERT(tol.approximately_equal(u, u_ref));
877  TEST_ASSERT(tol.approximately_equal(v, v_ref));
878  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
879 
880  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref);
881  TEST_ASSERT(tol.approximately_equal(u, u_ref));
882  TEST_ASSERT(tol.approximately_equal(v, v_ref));
883  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
884 
885  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
886  TEST_ASSERT(tol.approximately_equal(u, u_ref));
887  TEST_ASSERT(tol.approximately_equal(v, v_ref));
888  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
889 
890  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
891  TEST_ASSERT(tol.approximately_equal(u, u_ref));
892  TEST_ASSERT(tol.approximately_equal(v, v_ref));
893  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
894 
895  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
896  TEST_ASSERT(tol.approximately_equal(u, u_ref));
897  TEST_ASSERT(tol.approximately_equal(v, v_ref));
898  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
899 
900  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
901  TEST_ASSERT(tol.approximately_equal(u, u_ref));
902  TEST_ASSERT(tol.approximately_equal(v, v_ref));
903  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
904 
905  // test point near corner of surface
906  dist_ref=static_cast<data_type>(0.1);
907  u_ref=static_cast<data_type>(0.01);
908  v_ref=static_cast<data_type>(0.999);
909  norm=s.normal(u_ref, v_ref);
910  pt=s.f(u_ref, v_ref)+dist_ref*norm;
911  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
912  TEST_ASSERT(tol.approximately_equal(u, u_ref));
913  TEST_ASSERT(tol.approximately_equal(v, v_ref));
914  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
915 
916  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
917  TEST_ASSERT(tol.approximately_equal(u, u_ref));
918  TEST_ASSERT(tol.approximately_equal(v, v_ref));
919  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
920 
921  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref);
922  TEST_ASSERT(tol.approximately_equal(u, u_ref));
923  TEST_ASSERT(tol.approximately_equal(v, v_ref));
924  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
925 
926  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
927  TEST_ASSERT(tol.approximately_equal(u, u_ref));
928  TEST_ASSERT(tol.approximately_equal(v, v_ref));
929  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
930 
931  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref-v_off);
932  TEST_ASSERT(tol.approximately_equal(u, u_ref));
933  TEST_ASSERT(tol.approximately_equal(v, v_ref));
934  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
935 
936  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
937  TEST_ASSERT(tol.approximately_equal(u, u_ref));
938  TEST_ASSERT(tol.approximately_equal(v, v_ref));
939  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
940 
941  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
942  TEST_ASSERT(tol.approximately_equal(u, u_ref));
943  TEST_ASSERT(tol.approximately_equal(v, v_ref));
944  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
945 
946  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
947  TEST_ASSERT(tol.approximately_equal(u, u_ref));
948  TEST_ASSERT(tol.approximately_equal(v, v_ref));
949  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
950 
951  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
952  TEST_ASSERT(tol.approximately_equal(u, u_ref));
953  TEST_ASSERT(tol.approximately_equal(v, v_ref));
954  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
955 
956  // test point near corner of surface
957  dist_ref=static_cast<data_type>(0.1);
958  u_ref=static_cast<data_type>(0.999);
959  v_ref=static_cast<data_type>(0.999);
960  norm=s.normal(u_ref, v_ref);
961  pt=s.f(u_ref, v_ref)+dist_ref*norm;
962  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
963  TEST_ASSERT(tol.approximately_equal(u, u_ref));
964  TEST_ASSERT(tol.approximately_equal(v, v_ref));
965  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
966 
967  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
968  TEST_ASSERT(tol.approximately_equal(u, u_ref));
969  TEST_ASSERT(tol.approximately_equal(v, v_ref));
970  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
971 
972  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref-v_off);
973  TEST_ASSERT(tol.approximately_equal(u, u_ref));
974  TEST_ASSERT(tol.approximately_equal(v, v_ref));
975  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
976 
977  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref);
978  TEST_ASSERT(tol.approximately_equal(u, u_ref));
979  TEST_ASSERT(tol.approximately_equal(v, v_ref));
980  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
981 
982  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
983  TEST_ASSERT(tol.approximately_equal(u, u_ref));
984  TEST_ASSERT(tol.approximately_equal(v, v_ref));
985  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
986 
987  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
988  TEST_ASSERT(tol.approximately_equal(u, u_ref));
989  TEST_ASSERT(tol.approximately_equal(v, v_ref));
990  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
991 
992  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
993  TEST_ASSERT(tol.approximately_equal(u, u_ref));
994  TEST_ASSERT(tol.approximately_equal(v, v_ref));
995  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
996 
997  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
998  TEST_ASSERT(tol.approximately_equal(u, u_ref));
999  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1000  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1001 
1002  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
1003  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1004  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1005  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1006 
1007  // test point beyond edge of surface
1008  dist_ref=static_cast<data_type>(0.1);
1009  u_ref=static_cast<data_type>(1);
1010  v_ref=static_cast<data_type>(0.4);
1011  norm=s.normal(u_ref, v_ref);
1012  u_contra=-norm.cross(s.f_v(u_ref, v_ref));
1013  u_contra.normalize();
1014  pt=static_cast<data_type>(0.01)*u_contra+s.f(u_ref, v_ref)+dist_ref*norm;
1015  dist_ref=eli::geom::point::distance(pt, s.f(u_ref, v_ref));
1016  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1017  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1018  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1019  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1020 
1021  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1022  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1023  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1024  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1025 
1026  // Surface solver converges to nearby apparent solution.
1027  data_type u_alt, v_alt, dist_alt;
1028  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+v_off);
1029  u_alt=u;
1030  v_alt=v;
1031  dist_alt=dist;
1032 
1033  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+v_off);
1034  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1035  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1036  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1037 
1038  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref-v_off);
1039  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1040  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1041  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1042 
1043  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1044  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1045  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1046  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1047 
1048  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1049  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1050  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1051  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1052 
1053  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
1054  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1055  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1056  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1057 
1058  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
1059  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1060  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1061  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1062 
1063  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
1064  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1065  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1066  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1067 
1068  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
1069  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1070  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1071  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1072 
1073  // test point beyond edge of surface
1074  dist_ref=static_cast<data_type>(0.1);
1075  u_ref=static_cast<data_type>(0.6);
1076  v_ref=static_cast<data_type>(1);
1077  norm=s.normal(u_ref, v_ref);
1078  v_contra=norm.cross(s.f_u(u_ref, v_ref));
1079  v_contra.normalize();
1080  pt=static_cast<data_type>(0.01)*v_contra+s.f(u_ref, v_ref)+dist_ref*norm;
1081  dist_ref=eli::geom::point::distance(pt, s.f(u_ref, v_ref));
1082  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1083  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1084  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1085  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1086 
1087  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1088  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1089  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1090  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1091 
1092  // Surface solver converges to nearby apparent solution.
1093  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref);
1094  u_alt=u;
1095  v_alt=v;
1096  dist_alt=dist;
1097 
1098  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref);
1099  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1100  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1101  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1102 
1103  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1104  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1105  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1106  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1107 
1108  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref);
1109  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1110  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1111  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1112 
1113  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1114  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1115  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1116  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1117 
1118  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
1119  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1120  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1121  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1122 
1123  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
1124  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1125  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1126  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1127 
1128  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
1129  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1130  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1131  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1132 
1133  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
1134  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1135  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1136  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1137 
1138  // test point beyond edge of surface
1139  dist_ref=static_cast<data_type>(0.5);
1140  u_ref=static_cast<data_type>(0);
1141  v_ref=static_cast<data_type>(0.2);
1142  norm=s.normal(u_ref, v_ref);
1143  u_contra=-norm.cross(s.f_v(u_ref, v_ref));
1144  u_contra.normalize();
1145  pt=static_cast<data_type>(-0.1)*u_contra+s.f(u_ref, v_ref)+dist_ref*norm;
1146  dist_ref=eli::geom::point::distance(pt, s.f(u_ref, v_ref));
1147  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1148  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1149  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1150  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1151 
1152  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1153  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1154  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1155  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1156 
1157  // Surface solver converges to nearby apparent solution.
1158  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1159  u_alt=u;
1160  v_alt=v;
1161  dist_alt=dist;
1162 
1163  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1164  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1165  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1166  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1167 
1168  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1169  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1170  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1171  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1172 
1173  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+v_off);
1174  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1175  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1176  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1177 
1178  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref-v_off);
1179  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1180  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1181  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1182 
1183  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
1184  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1185  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1186  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1187 
1188  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
1189  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1190  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1191  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1192 
1193  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
1194  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1195  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1196  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1197 
1198  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
1199  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1200  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1201  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1202 
1203  // test point beyond edge of surface
1204  dist_ref=static_cast<data_type>(0.5);
1205  u_ref=static_cast<data_type>(0.2);
1206  v_ref=static_cast<data_type>(0);
1207  norm=s.normal(u_ref, v_ref);
1208  v_contra=norm.cross(s.f_u(u_ref, v_ref));
1209  v_contra.normalize();
1210  pt=static_cast<data_type>(-0.1)*v_contra+s.f(u_ref, v_ref)+dist_ref*norm;
1211  dist_ref=eli::geom::point::distance(pt, s.f(u_ref, v_ref));
1212  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1213  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1214  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1215  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1216 
1217  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1218  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1219  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1220  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1221 
1222  // Surface solver converges to nearby apparent solution.
1223  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+static_cast<data_type>(0.02));
1224  u_alt=u;
1225  v_alt=v;
1226  dist_alt=dist;
1227 
1228  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref+static_cast<data_type>(0.02));
1229  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1230  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1231  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1232 
1233  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1234  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1235  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1236  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1237 
1238  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref);
1239  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1240  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1241  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1242 
1243  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1244  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1245  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1246  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1247 
1248  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref);
1249  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1250  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1251  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1252 
1253  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 0);
1254  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1255  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1256  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1257 
1258  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0, 1);
1259  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1260  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1261  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1262 
1263  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 0);
1264  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1265  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1266  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1267 
1268  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1, 1);
1269  TEST_ASSERT(tol.approximately_equal(u, u_alt));
1270  TEST_ASSERT(tol.approximately_equal(v, v_alt));
1271  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
1272 
1273  }
1274 
1276  {
1277  const index_type n(12), m(3);
1278  surface_type s(n, m);
1279  point_type cp[n+1], offset[m+1], pt_out;
1280  point_type pt, norm, u_contra, v_contra;
1281  data_type z[m+1], dist, u, v, dist_ref, u_ref, v_ref;
1282  data_type u_off(static_cast<data_type>(0.1)), v_off(static_cast<data_type>(0.1));
1283  index_type i, j;
1284 
1285  // set control points
1286  cp[0] << 1, 0, 0;
1287  cp[1] << 1, 0.5, 0;
1288  cp[2] << 0.5, 1, 0;
1289  cp[3] << 0, 1, 0;
1290  cp[4] <<-0.5, 1, 0;
1291  cp[5] << -1, 0.5, 0;
1292  cp[6] << -1, 0, 0;
1293  cp[7] << -1,-0.5, 0;
1294  cp[8] <<-0.5,-1, 0;
1295  cp[9] << 0,-1, 0;
1296  cp[10] << 0.5,-1, 0;
1297  cp[11] << 1,-0.5, 0;
1298  cp[12] << 1,0, 0;
1299  z[0]=-0.5;
1300  z[1]=0;
1301  z[2]=0.5;
1302  z[3]=1;
1303  offset[0] << 0, 0, 0;
1304  offset[1] << 0.5, 0, 0;
1305  offset[2] << -0.5, 0.5, 0;
1306  offset[3] << 0, 0, 0;
1307 
1308  // create surface with specified dimensions and set control points
1309  for (j=0; j<=m; ++j)
1310  {
1311  for (i=0; i<=n; ++i)
1312  {
1313  cp[i].z() = z[j];
1314  s.set_control_point(cp[i]+offset[j], i, j);
1315  }
1316  }
1317  TEST_ASSERT(s.closed_u());
1318  TEST_ASSERT(s.open_v());
1319 
1320  // test point on surface
1321  dist_ref=0;
1322  u_ref=static_cast<data_type>(0.35);
1323  v_ref=static_cast<data_type>(0.35);
1324  norm=s.normal(u_ref, v_ref);
1325  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1326  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1327  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1328  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1329  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1330 
1331  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1332  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1333  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1334  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1335 
1336  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1337  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1338  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1339  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1340 
1341  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1342  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1343  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1344  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1345 
1346  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1347  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1348  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1349  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1350 
1351  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1352  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1353  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1354  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1355 
1356  // test point very near surface
1357  dist_ref=static_cast<data_type>(0.01);
1358  u_ref=static_cast<data_type>(0.35);
1359  v_ref=static_cast<data_type>(0.35);
1360  norm=-s.normal(u_ref, v_ref);
1361  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1362  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1363  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1364  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1365  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1366 
1367  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1368  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1369  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1370  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1371 
1372  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1373  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1374  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1375  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1376 
1377  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1378  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1379  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1380  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1381 
1382  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1383  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1384  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1385  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1386 
1387  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1388  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1389  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1390  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1391 
1392  // test point near surface
1393  dist_ref=static_cast<data_type>(0.1);
1394  u_ref=static_cast<data_type>(0.35);
1395  v_ref=static_cast<data_type>(0.35);
1396  norm=-s.normal(u_ref, v_ref);
1397  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1398  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1399  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1400  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1401  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1402 
1403  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1404  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1405  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1406  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1407 
1408  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1409  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1410  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1411  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1412 
1413  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1414  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1415  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1416  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1417 
1418  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1419  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1420  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1421  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1422 
1423  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1424  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1425  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1426  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1427 
1428  // test point near center surface
1429  dist_ref=static_cast<data_type>(0.72);
1430  u_ref=static_cast<data_type>(0.35);
1431  v_ref=static_cast<data_type>(0.35);
1432  norm=-s.normal(u_ref, v_ref);
1433  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1434  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1435  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1436  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1437  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1438 
1439  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1440  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1441  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1442  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1443 
1444  // +v_off cases seek local maximum.
1445  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1446  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1447  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1448  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1449 
1450  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1451  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1452  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1453  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1454 
1455  // test point near and outside surface
1456  dist_ref=static_cast<data_type>(0.1);
1457  u_ref=static_cast<data_type>(0.35);
1458  v_ref=static_cast<data_type>(0.35);
1459  norm=s.normal(u_ref, v_ref);
1460  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1461  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1462  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1463  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1464  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1465 
1466  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1467  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1468  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1469  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1470 
1471  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1472  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1473  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1474  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1475 
1476  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1477  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1478  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1479  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1480 
1481  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1482  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1483  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1484  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1485 
1486  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1487  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1488  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1489  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1490 
1491  // test point far and outside surface
1492  dist_ref=3;
1493  u_ref=static_cast<data_type>(0.25);
1494  v_ref=static_cast<data_type>(0.7);
1495  norm=s.normal(u_ref, v_ref);
1496  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1497  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1498  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1499  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1500  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1501 
1502  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1503  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1504  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1505  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1506 
1507  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1508  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1509  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1510  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1511 
1512  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1513  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1514  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1515  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1516 
1517  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1518  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1519  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1520  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1521 
1522  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1523  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1524  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1525  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1526 
1527  // test point near end of surface
1528  dist_ref=static_cast<data_type>(0.1);
1529  u_ref=static_cast<data_type>(0.25);
1530  v_ref=static_cast<data_type>(0.999);
1531  norm=-s.normal(u_ref, v_ref);
1532  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1533  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1534  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1535  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1536  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1537 
1538  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1539  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1540  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1541  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1542 
1543  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1544  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1545  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1546  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1547 
1548  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1549  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1550  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1551  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1552 
1553  // test point near end and outside of surface
1554  dist_ref=static_cast<data_type>(0.1);
1555  u_ref=static_cast<data_type>(0.25);
1556  v_ref=static_cast<data_type>(0.999);
1557  norm=s.normal(u_ref, v_ref);
1558  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1559  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1560  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1561  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1562  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1563 
1564  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1565  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1566  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1567  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1568 
1569  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1570  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1571  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1572  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1573 
1574  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1575  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1576  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1577  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1578 
1579  // test point near end of surface
1580  dist_ref=static_cast<data_type>(0.1);
1581  u_ref=static_cast<data_type>(0.25);
1582  v_ref=static_cast<data_type>(0.001);
1583  norm=-s.normal(u_ref, v_ref);
1584  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1585  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1586  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1587  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1588  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1589 
1590  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1591  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1592  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1593  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1594 
1595  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1596  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1597  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1598  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1599 
1600  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1601  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1602  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1603  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1604 
1605  // test point near end and outside of surface
1606  dist_ref=static_cast<data_type>(0.1);
1607  u_ref=static_cast<data_type>(0.25);
1608  v_ref=static_cast<data_type>(0.001);
1609  norm=s.normal(u_ref, v_ref);
1610  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1611  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1612  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1613  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1614  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1615 
1616  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1617  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1618  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1619  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1620 
1621  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1622  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1623  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1624  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1625 
1626  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1627  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1628  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1629  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1630 
1631  // test point near closed portion of surface
1632  dist_ref=static_cast<data_type>(0.1);
1633  u_ref=static_cast<data_type>(0.001);
1634  v_ref=static_cast<data_type>(0.3);
1635  norm=-s.normal(u_ref, v_ref);
1636  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1637  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1638  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1639  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1640  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1641 
1642  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1643  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1644  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1645  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1646 
1647  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1648  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1649  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1650  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1651 
1652  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1653  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1654  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1655  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1656 
1657  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref);
1658  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1659  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1660  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1661 
1662  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref+v_off);
1663  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1664  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1665  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1666 
1667  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref-v_off);
1668  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1669  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1670  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1671 
1672  // test point near closed portion and outside of surface
1673  dist_ref=static_cast<data_type>(0.1);
1674  u_ref=static_cast<data_type>(0.001);
1675  v_ref=static_cast<data_type>(0.3);
1676  norm=s.normal(u_ref, v_ref);
1677  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1678  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1679  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1680  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1681  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1682 
1683  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1684  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1685  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1686  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1687 
1688  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref+v_off);
1689  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1690  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1691  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1692 
1693  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref+u_off, v_ref-v_off);
1694  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1695  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1696  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1697 
1698  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref);
1699  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1700  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1701  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1702 
1703  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref+v_off);
1704  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1705  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1706  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1707 
1708  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 1-u_off, v_ref-v_off);
1709  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1710  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1711  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1712 
1713  // test point near closed portion of surface
1714  dist_ref=static_cast<data_type>(0.1);
1715  u_ref=static_cast<data_type>(0.999);
1716  v_ref=static_cast<data_type>(0.3);
1717  norm=-s.normal(u_ref, v_ref);
1718  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1719  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1720  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1721  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1722  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1723 
1724  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1725  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1726  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1727  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1728 
1729  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref+v_off);
1730  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1731  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1732  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1733 
1734  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref-v_off);
1735  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1736  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1737  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1738 
1739  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref);
1740  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1741  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1742  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1743 
1744  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1745  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1746  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1747  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1748 
1749  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1750  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1751  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1752  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1753 
1754  // test point near closed portion and outside of surface
1755  dist_ref=static_cast<data_type>(0.1);
1756  u_ref=static_cast<data_type>(0.999);
1757  v_ref=static_cast<data_type>(0.3);
1758  norm=s.normal(u_ref, v_ref);
1759  pt=s.f(u_ref, v_ref)+dist_ref*norm;
1760  dist=eli::geom::intersect::minimum_distance(u, v, s, pt);
1761  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1762  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1763  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1764 
1765  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref, v_ref);
1766  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1767  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1768  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1769 
1770  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref+v_off);
1771  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1772  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1773  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1774 
1775  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref-v_off);
1776  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1777  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1778  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1779 
1780  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, 0+u_off, v_ref);
1781  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1782  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1783  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1784 
1785  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref+v_off);
1786  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1787  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1788  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1789 
1790  dist=eli::geom::intersect::minimum_distance(u, v, s, pt, u_ref-u_off, v_ref-v_off);
1791  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1792  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1793  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1794 
1795 // if (typeid(data_type)==typeid(double))
1796 // {
1797 // std::cout << "% s_f(" << u_ref << ", " << v_ref << ")=" << s.f(u_ref, v_ref)
1798 // << "\ts_f(" << u << ", " << v << ")=" << s.f(u, v) << "\tpt=" << pt << std::endl;
1799 // std::cout << "% dist=" << dist << "\tdist_ref=" << dist_ref
1800 // << "\t(u, v)=(" << u << ", " << v << ")"
1801 // << "\t(u_ref, v_ref)=(" << u_ref << ", " << v_ref << ")" << std::endl;
1802 // std::vector<point_type> vec(3);
1803 // vec[0]=pt;
1804 // vec[1]=s.f(u_ref, v_ref);
1805 // vec[2]=s.f(u, v);
1806 // octave_print(1, vec, s);
1807 // }
1808  }
1809 
1811  {
1812  const index_type n(3), m(3);
1813  surface_type s(n, m);
1814  point_type cp[3+1][3+1], pt_out;
1815  point_type pt, norm, u_contra, v_contra;
1816  data_type dist, u, v, dist_ref, u_ref, v_ref;
1817  data_type u_off(static_cast<data_type>(0.2)), v_off(static_cast<data_type>(0.2));
1818  index_type i, j;
1819  piecewise_surface_type pws;
1821 
1822  pws.init_uv(1, 1);
1823 
1824  // create surface with specified control points
1825  cp[0][0] << -15, 0, 15;
1826  cp[1][0] << -5, 5, 15;
1827  cp[2][0] << 5, 5, 15;
1828  cp[3][0] << 15, 0, 15;
1829  cp[0][1] << -15, 5, 5;
1830  cp[1][1] << -5, 5, 5;
1831  cp[2][1] << 5, 5, 5;
1832  cp[3][1] << 15, 5, 5;
1833  cp[0][2] << -15, 5, -5;
1834  cp[1][2] << -5, 5, -5;
1835  cp[2][2] << 5, 5, -5;
1836  cp[3][2] << 15, 5, -5;
1837  cp[0][3] << -15, 0, -15;
1838  cp[1][3] << -5, 5, -15;
1839  cp[2][3] << 5, 5, -15;
1840  cp[3][3] << 15, 0, -15;
1841 
1842  // create surface with specified dimensions and set control points
1843  for (i=0; i<=n; ++i)
1844  {
1845  for (j=0; j<=m; ++j)
1846  {
1847  s.set_control_point(cp[i][j], i, j);
1848  }
1849  }
1850  TEST_ASSERT(s.open_u());
1851  TEST_ASSERT(s.open_v());
1852 
1853  err=pws.set(s, 0, 0);
1854  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
1855 
1856  pws.split_u(static_cast<data_type>(0.2));
1857  pws.split_u(static_cast<data_type>(0.4));
1858  pws.split_u(static_cast<data_type>(0.6));
1859  pws.split_u(static_cast<data_type>(0.8));
1860 
1861  pws.split_v(static_cast<data_type>(0.2));
1862  pws.split_v(static_cast<data_type>(0.4));
1863  pws.split_v(static_cast<data_type>(0.6));
1864  pws.split_v(static_cast<data_type>(0.8));
1865 
1866  // test point on surface
1867  dist_ref=0;
1868  u_ref=0.25;
1869  v_ref=0.25;
1870  norm=pws.normal(u_ref, v_ref);
1871  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
1872 
1873  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
1874  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1875  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1876  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1877 
1878  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
1879  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1880  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1881  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1882 
1883  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
1884  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1885  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1886  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1887 
1888  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
1889  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1890  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1891  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1892 
1893  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
1894  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1895  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1896  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1897 
1898  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
1899  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1900  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1901  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1902 
1903  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
1904  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1905  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1906  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1907 
1908  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
1909  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1910  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1911  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1912 
1913  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
1914  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1915  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1916  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1917 
1918  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
1919  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1920  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1921  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1922 
1923  // test point very near surface
1924  dist_ref=static_cast<data_type>(0.01);
1925  u_ref=0.25;
1926  v_ref=0.25;
1927  norm=pws.normal(u_ref, v_ref);
1928  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
1929  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
1930  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1931  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1932  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1933 
1934  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
1935  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1936  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1937  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1938 
1939  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
1940  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1941  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1942  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1943 
1944  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
1945  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1946  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1947  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1948 
1949  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
1950  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1951  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1952  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1953 
1954  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
1955  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1956  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1957  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1958 
1959  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
1960  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1961  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1962  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1963 
1964  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
1965  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1966  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1967  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1968 
1969  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
1970  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1971  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1972  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1973 
1974  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
1975  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1976  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1977  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1978 
1979  // test point near surface
1980  dist_ref=static_cast<data_type>(0.1);
1981  u_ref=0.25;
1982  v_ref=0.25;
1983  norm=pws.normal(u_ref, v_ref);
1984  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
1985  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
1986  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1987  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1988  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1989 
1990  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
1991  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1992  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1993  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1994 
1995  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
1996  TEST_ASSERT(tol.approximately_equal(u, u_ref));
1997  TEST_ASSERT(tol.approximately_equal(v, v_ref));
1998  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
1999 
2000  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2001  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2002  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2003  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2004 
2005  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2006  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2007  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2008  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2009 
2010  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2011  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2012  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2013  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2014 
2015  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2016  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2017  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2018  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2019 
2020  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2021  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2022  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2023  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2024 
2025  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2026  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2027  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2028  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2029 
2030  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2031  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2032  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2033  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2034 
2035  // test point near and on concave side of surface
2036  dist_ref=static_cast<data_type>(0.1);
2037  u_ref=0.25;
2038  v_ref=0.25;
2039  norm=-pws.normal(u_ref, v_ref);
2040  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2041  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2042  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2043  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2044  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2045 
2046  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2047  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2048  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2049  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2050 
2051  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2052  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2053  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2054  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2055 
2056  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2057  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2058  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2059  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2060 
2061  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2062  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2063  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2064  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2065 
2066  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2067  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2068  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2069  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2070 
2071  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2072  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2073  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2074  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2075 
2076  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2077  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2078  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2079  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2080 
2081  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2082  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2083  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2084  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2085 
2086  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2087  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2088  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2089  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2090 
2091  // test point far surface
2092  dist_ref=static_cast<data_type>(1.1);
2093  u_ref=0.25;
2094  v_ref=0.25;
2095  norm=pws.normal(u_ref, v_ref);
2096  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2097  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2098  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2099  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2100  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2101 
2102  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2103  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2104  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2105  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2106 
2107  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2108  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2109  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2110  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2111 
2112  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2113  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2114  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2115  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2116 
2117  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2118  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2119  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2120  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2121 
2122  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2123  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2124  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2125  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2126 
2127  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2128  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2129  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2130  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2131 
2132  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2133  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2134  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2135  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2136 
2137  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2138  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2139  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2140  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2141 
2142  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2143  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2144  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2145  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2146 
2147  // test point on surface
2148  dist_ref=0;
2149  u_ref=static_cast<data_type>(0.64);
2150  v_ref=static_cast<data_type>(0.32);
2151  norm=pws.normal(u_ref, v_ref);
2152  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2153  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2154  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2155  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2156  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2157 
2158  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2159  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2160  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2161  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2162 
2163  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2164  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2165  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2166  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2167 
2168  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2169  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2170  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2171  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2172 
2173  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2174  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2175  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2176  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2177 
2178  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2179  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2180  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2181  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2182 
2183  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2184  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2185  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2186  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2187 
2188  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2189  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2190  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2191  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2192 
2193  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2194  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2195  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2196  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2197 
2198  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2199  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2200  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2201  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2202 
2203  // test point very near surface
2204  dist_ref=static_cast<data_type>(0.01);
2205  u_ref=static_cast<data_type>(0.64);
2206  v_ref=static_cast<data_type>(0.32);
2207  norm=pws.normal(u_ref, v_ref);
2208  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2209  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2210  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2211  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2212  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2213 
2214  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2215  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2216  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2217  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2218 
2219  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2220  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2221  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2222  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2223 
2224  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2225  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2226  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2227  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2228 
2229  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2230  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2231  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2232  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2233 
2234  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2235  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2236  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2237  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2238 
2239  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2240  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2241  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2242  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2243 
2244  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2245  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2246  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2247  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2248 
2249  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2250  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2251  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2252  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2253 
2254  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2255  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2256  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2257  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2258 
2259  // test point near surface
2260  dist_ref=static_cast<data_type>(0.1);
2261  u_ref=static_cast<data_type>(0.64);
2262  v_ref=static_cast<data_type>(0.32);
2263  norm=pws.normal(u_ref, v_ref);
2264  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2265  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2266  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2267  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2268  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2269 
2270  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2271  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2272  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2273  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2274 
2275  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2276  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2277  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2278  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2279 
2280  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2281  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2282  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2283  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2284 
2285  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2286  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2287  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2288  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2289 
2290  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2291  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2292  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2293  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2294 
2295  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2296  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2297  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2298  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2299 
2300  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2301  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2302  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2303  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2304 
2305  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2306  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2307  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2308  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2309 
2310  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2311  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2312  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2313  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2314 
2315  // test point near and on concave side of surface
2316  dist_ref=static_cast<data_type>(0.1);
2317  u_ref=static_cast<data_type>(0.64);
2318  v_ref=static_cast<data_type>(0.32);
2319  norm=-pws.normal(u_ref, v_ref);
2320  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2321  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2322  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2323  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2324  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2325 
2326  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2327  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2328  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2329  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2330 
2331  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2332  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2333  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2334  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2335 
2336  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2337  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2338  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2339  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2340 
2341  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2342  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2343  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2344  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2345 
2346  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2347  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2348  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2349  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2350 
2351  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2352  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2353  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2354  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2355 
2356  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2357  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2358  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2359  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2360 
2361  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2362  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2363  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2364  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2365 
2366  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2367  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2368  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2369  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2370 
2371  // test point near surface
2372  dist_ref=static_cast<data_type>(1.1);
2373  u_ref=static_cast<data_type>(0.64);
2374  v_ref=static_cast<data_type>(0.32);
2375  norm=pws.normal(u_ref, v_ref);
2376  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2377  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2378  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2379  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2380  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2381 
2382  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2383  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2384  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2385  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2386 
2387  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2388  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2389  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2390  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2391 
2392  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2393  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2394  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2395  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2396 
2397  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2398  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2399  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2400  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2401 
2402  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2403  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2404  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2405  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2406 
2407  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2408  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2409  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2410  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2411 
2412  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2413  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2414  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2415  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2416 
2417  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2418  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2419  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2420  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2421 
2422  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2423  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2424  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2425  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2426 
2427  // test point near corner of surface
2428  dist_ref=static_cast<data_type>(0.1);
2429  u_ref=static_cast<data_type>(0.01);
2430  v_ref=static_cast<data_type>(0.01);
2431  norm=pws.normal(u_ref, v_ref);
2432  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2433  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2434  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2435  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2436  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2437 
2438  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2439  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2440  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2441  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2442 
2443  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2444  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2445  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2446  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2447 
2448  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
2449  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2450  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2451  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2452 
2453  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
2454  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2455  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2456  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2457 
2458  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2459  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2460  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2461  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2462 
2463  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2464  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2465  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2466  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2467 
2468  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2469  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2470  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2471  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2472 
2473  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2474  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2475  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2476  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2477 
2478  // test point near corner of surface
2479  dist_ref=static_cast<data_type>(0.1);
2480  u_ref=static_cast<data_type>(0.99);
2481  v_ref=static_cast<data_type>(0.01);
2482  norm=pws.normal(u_ref, v_ref);
2483  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2484  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2485  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2486  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2487  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2488 
2489  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2490  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2491  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2492  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2493 
2494  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
2495  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2496  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2497  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2498 
2499  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2500  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2501  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2502  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2503 
2504  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
2505  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2506  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2507  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2508 
2509  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2510  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2511  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2512  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2513 
2514  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2515  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2516  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2517  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2518 
2519  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2520  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2521  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2522  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2523 
2524  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2525  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2526  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2527  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2528 
2529  // test point near corner of surface
2530  dist_ref=static_cast<data_type>(0.1);
2531  u_ref=static_cast<data_type>(0.01);
2532  v_ref=static_cast<data_type>(0.999);
2533  norm=pws.normal(u_ref, v_ref);
2534  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2535  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2536  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2537  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2538  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2539 
2540  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2541  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2542  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2543  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2544 
2545  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
2546  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2547  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2548  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2549 
2550  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2551  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2552  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2553  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2554 
2555  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
2556  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2557  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2558  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2559 
2560  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2561  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2562  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2563  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2564 
2565  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2566  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2567  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2568  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2569 
2570  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2571  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2572  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2573  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2574 
2575  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2576  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2577  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2578  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2579 
2580  // test point near corner of surface
2581  dist_ref=static_cast<data_type>(0.1);
2582  u_ref=static_cast<data_type>(0.999);
2583  v_ref=static_cast<data_type>(0.999);
2584  norm=pws.normal(u_ref, v_ref);
2585  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
2586  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2587  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2588  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2589  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2590 
2591  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2592  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2593  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2594  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2595 
2596  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
2597  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2598  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2599  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2600 
2601  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
2602  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2603  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2604  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2605 
2606  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2607  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2608  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2609  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2610 
2611  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2612  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2613  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2614  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2615 
2616  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2617  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2618  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2619  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2620 
2621  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2622  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2623  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2624  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2625 
2626  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2627  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2628  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2629  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2630 
2631  // test point beyond edge of surface
2632  dist_ref=static_cast<data_type>(0.1);
2633  u_ref=static_cast<data_type>(1);
2634  v_ref=static_cast<data_type>(0.4);
2635  norm=pws.normal(u_ref, v_ref);
2636  u_contra=-norm.cross(pws.f_v(u_ref, v_ref));
2637  u_contra.normalize();
2638  pt=static_cast<data_type>(0.01)*u_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
2639  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
2640  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2641  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2642  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2643  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2644 
2645  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2646  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2647  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2648  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2649 
2650  // Surface solver converges to nearby apparent solution.
2651  data_type u_alt, v_alt, dist_alt;
2652  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
2653  u_alt=u;
2654  v_alt=v;
2655  dist_alt=dist;
2656 
2657  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
2658  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2659  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2660  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2661 
2662  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
2663  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2664  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2665  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2666 
2667  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2668  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2669  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2670  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2671 
2672  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2673  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2674  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2675  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2676 
2677  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2678  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2679  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2680  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2681 
2682  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2683  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2684  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2685  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2686 
2687  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2688  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2689  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2690  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2691 
2692  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2693  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2694  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2695  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2696 
2697  // test point beyond edge of surface
2698  dist_ref=static_cast<data_type>(0.1);
2699  u_ref=static_cast<data_type>(0.6);
2700  v_ref=static_cast<data_type>(1);
2701  norm=pws.normal(u_ref, v_ref);
2702  v_contra=norm.cross(pws.f_u(u_ref, v_ref));
2703  v_contra.normalize();
2704  pt=static_cast<data_type>(0.01)*v_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
2705  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
2706  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2707  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2708  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2709  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2710 
2711  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2712  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2713  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2714  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2715 
2716  // Surface solver converges to nearby apparent solution.
2717  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
2718  u_alt=u;
2719  v_alt=v;
2720  dist_alt=dist;
2721 
2722  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
2723  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2724  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2725  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2726 
2727  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2728  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2729  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2730  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2731 
2732  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
2733  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2734  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2735  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2736 
2737  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
2738  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2739  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2740  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2741 
2742  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2743  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2744  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2745  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2746 
2747  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2748  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2749  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2750  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2751 
2752  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2753  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2754  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2755  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2756 
2757  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2758  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2759  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2760  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2761 
2762  // test point beyond edge of surface
2763  dist_ref=static_cast<data_type>(0.5);
2764  u_ref=static_cast<data_type>(0);
2765  v_ref=static_cast<data_type>(0.2);
2766  norm=pws.normal(u_ref, v_ref);
2767  u_contra=-norm.cross(pws.f_v(u_ref, v_ref));
2768  u_contra.normalize();
2769  pt=static_cast<data_type>(-0.1)*u_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
2770  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
2771  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2772  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2773  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2774  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2775 
2776  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2777  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2778  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2779  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2780 
2781  // Surface solver converges to nearby apparent solution.
2782  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2783  u_alt=u;
2784  v_alt=v;
2785  dist_alt=dist;
2786 
2787  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2788  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2789  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2790  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2791 
2792  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
2793  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2794  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2795  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2796 
2797  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
2798  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2799  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2800  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2801 
2802  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
2803  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2804  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2805  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2806 
2807  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2808  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2809  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2810  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2811 
2812  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2813  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2814  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2815  if (typeid(data_type)==typeid(float))
2816  {
2817  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2818  }
2819  else
2820  {
2821  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2822  }
2823 
2824  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2825  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2826  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2827  if (typeid(data_type)==typeid(float))
2828  {
2829  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2830  }
2831  else
2832  {
2833  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2834  }
2835 
2836  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2837  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2838  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2839  if (typeid(data_type)==typeid(float))
2840  {
2841  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2842  }
2843  else
2844  {
2845  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2846  }
2847 
2848  // test point beyond edge of surface
2849  dist_ref=static_cast<data_type>(0.5);
2850  u_ref=static_cast<data_type>(0.2);
2851  v_ref=static_cast<data_type>(0);
2852  norm=pws.normal(u_ref, v_ref);
2853  v_contra=norm.cross(pws.f_u(u_ref, v_ref));
2854  v_contra.normalize();
2855  pt=static_cast<data_type>(-0.1)*v_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
2856  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
2857  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
2858  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2859  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2860  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2861 
2862  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
2863  TEST_ASSERT(tol.approximately_equal(u, u_ref));
2864  TEST_ASSERT(tol.approximately_equal(v, v_ref));
2865  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
2866 
2867  // Surface solver converges to nearby apparent solution.
2868  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+static_cast<data_type>(0.02));
2869  u_alt=u;
2870  v_alt=v;
2871  dist_alt=dist;
2872 
2873  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+static_cast<data_type>(0.02));
2874  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2875  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2876  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2877 
2878  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
2879  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2880  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2881  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2882 
2883  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
2884  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2885  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2886  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2887 
2888  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
2889  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2890  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2891  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2892 
2893  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
2894  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2895  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2896  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2897 
2898  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 0);
2899  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2900  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2901  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2902 
2903  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0, 1);
2904  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2905  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2906  if (typeid(data_type)==typeid(float))
2907  {
2908  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2909  }
2910  else
2911  {
2912  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2913  }
2914 
2915  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 0);
2916  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2917  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2918  if (typeid(data_type)==typeid(float))
2919  {
2920  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2921  }
2922  else
2923  {
2924  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2925  }
2926 
2927  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1, 1);
2928  TEST_ASSERT(tol.approximately_equal(u, u_alt));
2929  TEST_ASSERT(tol.approximately_equal(v, v_alt));
2930  if (typeid(data_type)==typeid(float))
2931  {
2932  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
2933  }
2934  else
2935  {
2936  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
2937  }
2938  }
2939 
2941  {
2942  const index_type n(3), m(3);
2943  surface_type s(n, m);
2944  point_type cp[3+1][3+1], pt_out;
2945  point_type pt, norm, u_contra, v_contra;
2946  data_type dist, u, v, dist_ref, u_ref, v_ref;
2947  data_type u_off(static_cast<data_type>(0.2)), v_off(static_cast<data_type>(0.2));
2948  index_type i, j;
2949  piecewise_surface_type pws;
2951 
2952  pws.init_uv(1, 1);
2953 
2954  // create surface with specified control points
2955  cp[0][0] << -15, 0, 15;
2956  cp[1][0] << -5, 5, 15;
2957  cp[2][0] << 5, 5, 15;
2958  cp[3][0] << 15, 0, 15;
2959  cp[0][1] << -15, 5, 5;
2960  cp[1][1] << -5, 5, 5;
2961  cp[2][1] << 5, 5, 5;
2962  cp[3][1] << 15, 5, 5;
2963  cp[0][2] << -15, 5, -5;
2964  cp[1][2] << -5, 5, -5;
2965  cp[2][2] << 5, 5, -5;
2966  cp[3][2] << 15, 5, -5;
2967  cp[0][3] << -15, 0, -15;
2968  cp[1][3] << -5, 5, -15;
2969  cp[2][3] << 5, 5, -15;
2970  cp[3][3] << 15, 0, -15;
2971 
2972  // create surface with specified dimensions and set control points
2973  for (i=0; i<=n; ++i)
2974  {
2975  for (j=0; j<=m; ++j)
2976  {
2977  s.set_control_point(cp[i][j], i, j);
2978  }
2979  }
2980  TEST_ASSERT(s.open_u());
2981  TEST_ASSERT(s.open_v());
2982 
2983  err=pws.set(s, 0, 0);
2984  TEST_ASSERT(err==piecewise_surface_type::NO_ERRORS);
2985 
2986  data_type u0(static_cast<data_type>(1.4));
2987  data_type v0(static_cast<data_type>(2.2));
2988 
2989  pws.set_u0(u0);
2990  pws.set_v0(v0);
2991 
2992  pws.split_u(u0+static_cast<data_type>(0.2));
2993  pws.split_u(u0+static_cast<data_type>(0.4));
2994  pws.split_u(u0+static_cast<data_type>(0.6));
2995  pws.split_u(u0+static_cast<data_type>(0.8));
2996 
2997  pws.split_v(v0+static_cast<data_type>(0.2));
2998  pws.split_v(v0+static_cast<data_type>(0.4));
2999  pws.split_v(v0+static_cast<data_type>(0.6));
3000  pws.split_v(v0+static_cast<data_type>(0.8));
3001 
3002  // test point on surface
3003  dist_ref=0;
3004  u_ref=static_cast<data_type>(0.25)+u0;
3005  v_ref=static_cast<data_type>(0.25)+v0;
3006  norm=pws.normal(u_ref, v_ref);
3007  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3008  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3009  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3010  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3011  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3012 
3013  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3014  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3015  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3016  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3017 
3018  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3019  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3020  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3021  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3022 
3023  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3024  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3025  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3026  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3027 
3028  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3029  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3030  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3031  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3032 
3033  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3034  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3035  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3036  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3037 
3038  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3039  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3040  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3041  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3042 
3043  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3044  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3045  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3046  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3047 
3048  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3049  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3050  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3051  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3052 
3053  // test point very near surface
3054  dist_ref=static_cast<data_type>(0.01);
3055  u_ref=static_cast<data_type>(0.25)+u0;
3056  v_ref=static_cast<data_type>(0.25)+v0;
3057  norm=pws.normal(u_ref, v_ref);
3058  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3059  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3060  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3061  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3062  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3063 
3064  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3065  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3066  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3067  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3068 
3069  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3070  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3071  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3072  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3073 
3074  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3075  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3076  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3077  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3078 
3079  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3080  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3081  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3082  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3083 
3084  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3085  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3086  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3087  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3088 
3089  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3090  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3091  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3092  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3093 
3094  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3095  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3096  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3097  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3098 
3099  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3100  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3101  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3102  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3103 
3104  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3105  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3106  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3107  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3108 
3109  // test point near surface
3110  dist_ref=static_cast<data_type>(0.1);
3111  u_ref=static_cast<data_type>(0.25)+u0;
3112  v_ref=static_cast<data_type>(0.25)+v0;
3113  norm=pws.normal(u_ref, v_ref);
3114  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3115  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3116  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3117  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3118  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3119 
3120  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3121  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3122  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3123  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3124 
3125  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3126  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3127  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3128  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3129 
3130  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3131  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3132  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3133  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3134 
3135  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3136  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3137  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3138  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3139 
3140  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3141  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3142  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3143  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3144 
3145  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3146  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3147  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3148  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3149 
3150  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3151  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3152  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3153  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3154 
3155  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3156  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3157  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3158  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3159 
3160  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3161  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3162  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3163  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3164 
3165  // test point near and on concave side of surface
3166  dist_ref=static_cast<data_type>(0.1);
3167  u_ref=static_cast<data_type>(0.25)+u0;
3168  v_ref=static_cast<data_type>(0.25)+v0;
3169  norm=-pws.normal(u_ref, v_ref);
3170  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3171  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3172  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3173  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3174  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3175 
3176  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3177  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3178  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3179  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3180 
3181  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3182  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3183  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3184  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3185 
3186  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3187  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3188  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3189  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3190 
3191  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3192  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3193  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3194  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3195 
3196  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3197  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3198  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3199  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3200 
3201  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3202  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3203  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3204  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3205 
3206  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3207  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3208  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3209  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3210 
3211  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3212  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3213  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3214  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3215 
3216  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3217  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3218  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3219  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3220 
3221  // test point far surface
3222  dist_ref=static_cast<data_type>(1.1);
3223  u_ref=static_cast<data_type>(0.25)+u0;
3224  v_ref=static_cast<data_type>(0.25)+v0;
3225  norm=pws.normal(u_ref, v_ref);
3226  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3227  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3228  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3229  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3230  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3231 
3232  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3233  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3234  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3235  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3236 
3237  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3238  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3239  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3240  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3241 
3242  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3243  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3244  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3245  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3246 
3247  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3248  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3249  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3250  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3251 
3252  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3253  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3254  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3255  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3256 
3257  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3258  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3259  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3260  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3261 
3262  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3263  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3264  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3265  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3266 
3267  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3268  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3269  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3270  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3271 
3272  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3273  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3274  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3275  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3276 
3277  // test point on surface
3278  dist_ref=0;
3279  u_ref=static_cast<data_type>(0.64)+u0;
3280  v_ref=static_cast<data_type>(0.32)+v0;
3281  norm=pws.normal(u_ref, v_ref);
3282  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3283  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3284  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3285  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3286  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3287 
3288  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3289  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3290  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3291  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3292 
3293  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3294  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3295  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3296  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3297 
3298  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3299  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3300  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3301  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3302 
3303  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3304  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3305  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3306  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3307 
3308  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3309  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3310  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3311  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3312 
3313  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3314  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3315  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3316  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3317 
3318  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3319  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3320  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3321  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3322 
3323  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3324  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3325  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3326  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3327 
3328  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3329  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3330  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3331  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3332 
3333  // test point very near surface
3334  dist_ref=static_cast<data_type>(0.01);
3335  u_ref=static_cast<data_type>(0.64)+u0;
3336  v_ref=static_cast<data_type>(0.32)+v0;
3337  norm=pws.normal(u_ref, v_ref);
3338  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3339  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3340  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3341  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3342  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3343 
3344  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3345  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3346  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3347  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3348 
3349  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3350  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3351  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3352  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3353 
3354  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3355  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3356  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3357  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3358 
3359  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3360  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3361  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3362  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3363 
3364  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3365  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3366  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3367  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3368 
3369  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3370  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3371  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3372  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3373 
3374  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3375  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3376  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3377  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3378 
3379  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3380  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3381  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3382  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3383 
3384  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3385  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3386  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3387  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3388 
3389  // test point near surface
3390  dist_ref=static_cast<data_type>(0.1);
3391  u_ref=static_cast<data_type>(0.64)+u0;
3392  v_ref=static_cast<data_type>(0.32)+v0;
3393  norm=pws.normal(u_ref, v_ref);
3394  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3395  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3396  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3397  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3398  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3399 
3400  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3401  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3402  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3403  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3404 
3405  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3406  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3407  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3408  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3409 
3410  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3411  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3412  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3413  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3414 
3415  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3416  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3417  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3418  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3419 
3420  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3421  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3422  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3423  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3424 
3425  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3426  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3427  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3428  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3429 
3430  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3431  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3432  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3433  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3434 
3435  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3436  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3437  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3438  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3439 
3440  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3441  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3442  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3443  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3444 
3445  // test point near and on concave side of surface
3446  dist_ref=static_cast<data_type>(0.1);
3447  u_ref=static_cast<data_type>(0.64)+u0;
3448  v_ref=static_cast<data_type>(0.32)+v0;
3449  norm=-pws.normal(u_ref, v_ref);
3450  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3451  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3452  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3453  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3454  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3455 
3456  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3457  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3458  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3459  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3460 
3461  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3462  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3463  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3464  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3465 
3466  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3467  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3468  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3469  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3470 
3471  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3472  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3473  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3474  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3475 
3476  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3477  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3478  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3479  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3480 
3481  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3482  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3483  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3484  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3485 
3486  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3487  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3488  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3489  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3490 
3491  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3492  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3493  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3494  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3495 
3496  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3497  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3498  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3499  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3500 
3501  // test point near surface
3502  dist_ref=static_cast<data_type>(1.1);
3503  u_ref=static_cast<data_type>(0.64)+u0;
3504  v_ref=static_cast<data_type>(0.32)+v0;
3505  norm=pws.normal(u_ref, v_ref);
3506  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3507  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3508  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3509  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3510  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3511 
3512  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3513  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3514  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3515  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3516 
3517  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3518  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3519  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3520  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3521 
3522  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3523  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3524  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3525  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3526 
3527  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3528  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3529  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3530  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3531 
3532  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3533  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3534  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3535  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3536 
3537  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3538  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3539  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3540  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3541 
3542  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3543  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3544  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3545  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3546 
3547  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3548  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3549  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3550  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3551 
3552  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3553  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3554  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3555  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3556 
3557  // test point near corner of surface
3558  dist_ref=static_cast<data_type>(0.1);
3559  u_ref=static_cast<data_type>(0.01)+u0;
3560  v_ref=static_cast<data_type>(0.01)+v0;
3561  norm=pws.normal(u_ref, v_ref);
3562  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3563  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3564  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3565  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3566  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3567 
3568  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3569  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3570  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3571  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3572 
3573  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3574  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3575  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3576  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3577 
3578  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
3579  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3580  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3581  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3582 
3583  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
3584  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3585  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3586  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3587 
3588  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3589  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3590  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3591  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3592 
3593  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3594  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3595  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3596  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3597 
3598  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3599  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3600  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3601  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3602 
3603  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3604  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3605  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3606  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3607 
3608  // test point near corner of surface
3609  dist_ref=static_cast<data_type>(0.1);
3610  u_ref=static_cast<data_type>(0.99)+u0;
3611  v_ref=static_cast<data_type>(0.01)+v0;
3612  norm=pws.normal(u_ref, v_ref);
3613  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3614  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3615  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3616  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3617  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3618 
3619  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3620  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3621  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3622  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3623 
3624  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
3625  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3626  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3627  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3628 
3629  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3630  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3631  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3632  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3633 
3634  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
3635  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3636  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3637  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3638 
3639  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3640  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3641  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3642  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3643 
3644  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3645  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3646  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3647  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3648 
3649  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3650  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3651  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3652  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3653 
3654  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3655  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3656  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3657  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3658 
3659  // test point near corner of surface
3660  dist_ref=static_cast<data_type>(0.1);
3661  u_ref=static_cast<data_type>(0.01)+u0;
3662  v_ref=static_cast<data_type>(0.999)+v0;
3663  norm=pws.normal(u_ref, v_ref);
3664  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3665  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3666  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3667  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3668  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3669 
3670  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3671  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3672  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3673  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3674 
3675  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
3676  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3677  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3678  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3679 
3680  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3681  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3682  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3683  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3684 
3685  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
3686  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3687  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3688  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3689 
3690  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3691  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3692  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3693  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3694 
3695  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3696  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3697  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3698  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3699 
3700  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3701  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3702  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3703  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3704 
3705  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3706  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3707  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3708  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3709 
3710  // test point near corner of surface
3711  dist_ref=static_cast<data_type>(0.1);
3712  u_ref=static_cast<data_type>(0.999)+u0;
3713  v_ref=static_cast<data_type>(0.999)+v0;
3714  norm=pws.normal(u_ref, v_ref);
3715  pt=pws.f(u_ref, v_ref)+dist_ref*norm;
3716  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3717  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3718  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3719  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3720 
3721  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3722  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3723  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3724  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3725 
3726  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
3727  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3728  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3729  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3730 
3731  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
3732  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3733  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3734  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3735 
3736  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3737  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3738  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3739  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3740 
3741  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3742  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3743  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3744  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3745 
3746  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3747  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3748  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3749  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3750 
3751  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3752  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3753  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3754  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3755 
3756  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3757  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3758  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3759  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3760 
3761  // test point beyond edge of surface
3762  dist_ref=static_cast<data_type>(0.1);
3763  u_ref=static_cast<data_type>(1)+u0;
3764  v_ref=static_cast<data_type>(0.4)+v0;
3765  norm=pws.normal(u_ref, v_ref);
3766  u_contra=-norm.cross(pws.f_v(u_ref, v_ref));
3767  u_contra.normalize();
3768  pt=static_cast<data_type>(0.01)*u_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
3769  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
3770  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3771  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3772  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3773  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3774 
3775  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3776  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3777  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3778  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3779 
3780  // Surface solver converges to nearby apparent solution.
3781  data_type u_alt, v_alt, dist_alt;
3782  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
3783  u_alt=u;
3784  v_alt=v;
3785  dist_alt=dist;
3786 
3787  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
3788  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3789  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3790  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3791 
3792  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
3793  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3794  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3795  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3796 
3797  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
3798  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3799  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3800  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3801 
3802  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3803  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3804  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3805  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3806 
3807  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3808  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3809  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3810  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3811 
3812  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3813  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3814  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3815  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3816 
3817  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3818  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3819  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3820  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3821 
3822  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3823  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3824  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3825  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3826 
3827  // test point beyond edge of surface
3828  dist_ref=static_cast<data_type>(0.1);
3829  u_ref=static_cast<data_type>(0.6)+u0;
3830  v_ref=static_cast<data_type>(1)+v0;
3831  norm=pws.normal(u_ref, v_ref);
3832  v_contra=norm.cross(pws.f_u(u_ref, v_ref));
3833  v_contra.normalize();
3834  pt=static_cast<data_type>(0.01)*v_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
3835  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
3836  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3837  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3838  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3839  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3840 
3841  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3842  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3843  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3844  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3845 
3846  // Surface solver converges to nearby apparent solution.
3847  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
3848  u_alt=u;
3849  v_alt=v;
3850  dist_alt=dist;
3851 
3852  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
3853  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3854  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3855  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3856 
3857  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3858  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3859  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3860  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3861 
3862  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
3863  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3864  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3865  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3866 
3867  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref-v_off);
3868  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3869  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3870  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3871 
3872  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3873  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3874  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3875  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3876 
3877  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3878  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3879  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3880  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3881 
3882  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3883  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3884  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3885  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3886 
3887  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3888  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3889  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3890  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3891 
3892  // test point beyond edge of surface
3893  dist_ref=static_cast<data_type>(0.5);
3894  u_ref=static_cast<data_type>(0)+u0;
3895  v_ref=static_cast<data_type>(0.2)+v0;
3896  norm=pws.normal(u_ref, v_ref);
3897  u_contra=-norm.cross(pws.f_v(u_ref, v_ref));
3898  u_contra.normalize();
3899  pt=static_cast<data_type>(-0.1)*u_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
3900  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
3901  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3902  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3903  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3904  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3905 
3906  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3907  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3908  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3909  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3910 
3911  // Surface solver converges to nearby apparent solution.
3912  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3913  u_alt=u;
3914  v_alt=v;
3915  dist_alt=dist;
3916 
3917  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
3918  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3919  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3920  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3921 
3922  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref-v_off);
3923  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3924  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3925  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3926 
3927  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+v_off);
3928  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3929  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3930  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3931 
3932  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref-v_off);
3933  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3934  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3935  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3936 
3937  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
3938  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3939  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3940  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3941 
3942  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
3943  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3944  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3945  if (typeid(data_type)==typeid(float))
3946  {
3947  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
3948  }
3949  else
3950  {
3951  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3952  }
3953 
3954  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
3955  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3956  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3957  if (typeid(data_type)==typeid(float))
3958  {
3959  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
3960  }
3961  else
3962  {
3963  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3964  }
3965 
3966  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
3967  TEST_ASSERT(tol.approximately_equal(u, u_alt));
3968  TEST_ASSERT(tol.approximately_equal(v, v_alt));
3969  if (typeid(data_type)==typeid(float))
3970  {
3971  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
3972  }
3973  else
3974  {
3975  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
3976  }
3977 
3978  // test point beyond edge of surface
3979  dist_ref=static_cast<data_type>(0.5);
3980  u_ref=static_cast<data_type>(0.2)+u0;
3981  v_ref=static_cast<data_type>(0)+v0;
3982  norm=pws.normal(u_ref, v_ref);
3983  v_contra=norm.cross(pws.f_u(u_ref, v_ref));
3984  v_contra.normalize();
3985  pt=static_cast<data_type>(-0.1)*v_contra+pws.f(u_ref, v_ref)+dist_ref*norm;
3986  dist_ref=eli::geom::point::distance(pt, pws.f(u_ref, v_ref));
3987  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt);
3988  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3989  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3990  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3991 
3992  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref);
3993  TEST_ASSERT(tol.approximately_equal(u, u_ref));
3994  TEST_ASSERT(tol.approximately_equal(v, v_ref));
3995  TEST_ASSERT(tol.approximately_equal(dist, dist_ref));
3996 
3997  // Surface solver converges to nearby apparent solution.
3998  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+static_cast<data_type>(0.02));
3999  u_alt=u;
4000  v_alt=v;
4001  dist_alt=dist;
4002 
4003  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref, v_ref+static_cast<data_type>(0.02));
4004  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4005  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4006  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4007 
4008  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref+v_off);
4009  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4010  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4011  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4012 
4013  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref+u_off, v_ref);
4014  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4015  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4016  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4017 
4018  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref+v_off);
4019  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4020  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4021  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4022 
4023  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, u_ref-u_off, v_ref);
4024  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4025  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4026  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4027 
4028  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 0+v0);
4029  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4030  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4031  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4032 
4033  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 0+u0, 1+v0);
4034  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4035  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4036  if (typeid(data_type)==typeid(float))
4037  {
4038  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
4039  }
4040  else
4041  {
4042  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4043  }
4044 
4045  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 0+v0);
4046  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4047  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4048  if (typeid(data_type)==typeid(float))
4049  {
4050  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
4051  }
4052  else
4053  {
4054  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4055  }
4056 
4057  dist=eli::geom::intersect::minimum_distance(u, v, pws, pt, 1+u0, 1+v0);
4058  TEST_ASSERT(tol.approximately_equal(u, u_alt));
4059  TEST_ASSERT(tol.approximately_equal(v, v_alt));
4060  if (typeid(data_type)==typeid(float))
4061  {
4062  TEST_ASSERT(std::abs(dist-dist_alt) < 2e-3);
4063  }
4064  else
4065  {
4066  TEST_ASSERT(tol.approximately_equal(dist, dist_alt));
4067  }
4068  }
4069 
4070 
4071 };
4072 
4073 #endif
4074 
piecewise_surface_type::surface_type surface_type
Definition: minimum_distance_surface_test_suite.hpp:31
~minimum_distance_surface_test_suite()
Definition: minimum_distance_surface_test_suite.hpp:69
surface_type::index_type index_type
Definition: minimum_distance_surface_test_suite.hpp:33
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)
void point_piecewise_01_smooth_test()
Definition: minimum_distance_surface_test_suite.hpp:1810
Derived1__::Scalar distance(const Eigen::MatrixBase< Derived1__ > &p1, const Eigen::MatrixBase< Derived2__ > &p2)
Definition: distance.hpp:33
void point_smooth_test()
Definition: minimum_distance_surface_test_suite.hpp:204
void set_v0(const data_type &v0_in)
Definition: piecewise.hpp:137
eli::geom::surface::piecewise< eli::geom::surface::bezier, data_type, 3 > piecewise_surface_type
Definition: minimum_distance_surface_test_suite.hpp:30
point_type f_u(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:910
void set_u0(const data_type &u0_in)
Definition: piecewise.hpp:134
point_type f(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:897
surface_type::point_type point_type
Definition: minimum_distance_surface_test_suite.hpp:32
data__ data_type
Definition: minimum_distance_surface_test_suite.hpp:28
Definition: piecewise.hpp:37
surface_type::tolerance_type tolerance_type
Definition: minimum_distance_surface_test_suite.hpp:34
minimum_distance_surface_test_suite()
Definition: minimum_distance_surface_test_suite.hpp:65
void AddTests(const double &)
Definition: minimum_distance_surface_test_suite.hpp:47
error_code split_u(const data_type &u_in)
Definition: piecewise.hpp:582
void point_closed_test()
Definition: minimum_distance_surface_test_suite.hpp:1275
error_code split_v(const data_type &v_in)
Definition: piecewise.hpp:605
error_code
Definition: piecewise.hpp:69
void AddTests(const long double &)
Definition: minimum_distance_surface_test_suite.hpp:55
void octave_print(int figno, const std::vector< point_type > &pts, const surface_type &s) const
Definition: minimum_distance_surface_test_suite.hpp:74
void point_piecewise_trange_smooth_test()
Definition: minimum_distance_surface_test_suite.hpp:2940
Definition: piecewise.hpp:71
Definition: minimum_distance_surface_test_suite.hpp:25
point_type normal(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:1058
void AddTests(const float &)
Definition: minimum_distance_surface_test_suite.hpp:39
void init_uv(const index_type &nsegu, const index_type &nsegv, const data_type &du=1, const data_type &dv=1, const data_type &u0=0, const data_type &v0=0)
Definition: piecewise.hpp:219
surface__< data__, dim__, tol__ > surface_type
Definition: piecewise.hpp:57
error_code set(const surface_type &surf, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:509
tolerance_type tol
Definition: minimum_distance_surface_test_suite.hpp:36
point_type f_v(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:926