RINGMesh  Version 5.0.0
A programming library for geological model meshes
test-geometry-intersection.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #include <ringmesh/ringmesh_tests_config.h>
37 
38 #include <vector>
39 
40 #include <geogram/basic/vecg.h>
41 
43 
48 using namespace RINGMesh;
49 
50 void verdict( bool condition, std::string test_name )
51 {
52  if( !condition )
53  {
54  throw RINGMeshException( "TEST", test_name, ": KO" );
55  }
56  else
57  {
58  Logger::out( "TEST", test_name, ": OK" );
59  }
60 }
61 
62 template < index_t DIMENSION >
64  const vecn< DIMENSION >& vec0, const vecn< DIMENSION >& vec1 )
65 {
66  return ( vec0 - vec1 ).length2() < global_epsilon_sq;
67 }
68 
70 {
71  Logger::out( "TEST", "Test Line-Plane intersections" );
72  Geometry::Plane plane{ { 1., 0., 0. }, { 1., 4., -2 } };
73 
74  // Intersection is the origin point of the line
75  Geometry::Line3D line1{ { -2., 4., 1. }, { 1., 5., 0. } };
76  bool does_line1_intersect_plane;
77  vec3 result1;
78  std::tie( does_line1_intersect_plane, result1 ) =
79  Intersection::line_plane( line1, plane );
80  vec3 answer1{ line1.origin };
81  verdict( does_line1_intersect_plane && result1 == answer1,
82  "True intersection1" );
83 
84  // Intersection is a point
85  Geometry::Line3D line2{ { -2., 4., 1. }, { -41., 7., -28. } };
86  bool does_line2_intersect_plane;
87  vec3 result2;
88  std::tie( does_line2_intersect_plane, result2 ) =
89  Intersection::line_plane( line2, plane );
90  vec3 answer2{ 1., -77., -49. };
91  verdict( does_line2_intersect_plane && result2 == answer2,
92  "True intersection2" );
93 
94  // The line is parallel to the plane
95  Geometry::Line3D line3{ { 0., 2., 1. }, { 0., 1., 8. } };
96  bool does_line3_intersect_plane;
97  std::tie( does_line3_intersect_plane, std::ignore ) =
98  Intersection::line_plane( line3, plane );
99  verdict( !does_line3_intersect_plane, "Line parallel to the plane" );
100 
101  // The line is included into the plane
102  Geometry::Line3D line4{ { 0., 2., 1. }, { 1., 1., 8. } };
103  bool does_line4_intersect_plane;
104  std::tie( does_line4_intersect_plane, std::ignore ) =
105  Intersection::line_plane( line4, plane );
106  verdict( !does_line4_intersect_plane, "Line included into the plane" );
107 
108  Logger::out( "TEST", " " );
109 }
110 
112 {
113  Logger::out( "TEST", "Test Segment-Plane intersections" );
114  Geometry::Plane plane{ { 1., 1.25, -2 }, { 1., -2., 3. } };
115 
116  // Intersection is a point
117  Geometry::Segment3D seg1{ { 3., -1., 6.75 }, { -3., -10., -8.25 } };
118  bool does_seg1_intersect_plane;
119  vec3 result1;
120  std::tie( does_seg1_intersect_plane, result1 ) =
121  Intersection::segment_plane( seg1, plane );
122  vec3 answer1{ 1., -4., 1.75 };
123  verdict( does_seg1_intersect_plane && are_almost_equal( result1, answer1 ),
124  "True intersection" );
125 
126  // Intersection is an extremal point of the segment
127  Geometry::Segment3D seg2{ { 3., -1., 6.75 }, { 1., -4., 1.75 } };
128  bool does_seg2_intersect_plane;
129  vec3 result2;
130  std::tie( does_seg2_intersect_plane, result2 ) =
131  Intersection::segment_plane( seg2, plane );
132  vec3 answer2{ seg2.p1 };
133  verdict( does_seg2_intersect_plane && are_almost_equal( result2, answer2 ),
134  "Intersection at segment extremity" );
135 
136  // Line intersects but not the segment
137  Geometry::Segment3D seg3{ { 3., -1., 6.75 }, { 2., -2.5, 4.25 } };
138  bool does_seg3_intersect_plane;
139  std::tie( does_seg3_intersect_plane, std::ignore ) =
140  Intersection::segment_plane( seg3, plane );
141  verdict( !does_seg3_intersect_plane,
142  "Intersection on line but but into segment" );
143 
144  // The segment is parallel to the plane
145  Geometry::Segment3D seg4{ { 0., 0., 6.75 }, { 1., 0., 7.25 } };
146  bool does_seg4_intersect_plane;
147  std::tie( does_seg4_intersect_plane, std::ignore ) =
148  Intersection::segment_plane( seg4, plane );
149  verdict( !does_seg4_intersect_plane, "Segment parallel to plane" );
150 
151  // The segment is included into the plane
152  Geometry::Segment3D seg5{ { 5., -2., 5. }, { 1., -2., 3. } };
153  bool does_seg5_intersect_plane;
154  std::tie( does_seg5_intersect_plane, std::ignore ) =
155  Intersection::segment_plane( seg5, plane );
156  verdict( !does_seg5_intersect_plane, "Segment included into the plane" );
157 
158  Logger::out( "TEST", " " );
159 }
160 
162 {
163  Logger::out( "TEST", "Test Segment-Triangle intersections" );
164  Geometry::Triangle3D triangle{ { 1., 1., 0. }, { 2., 3., 0. },
165  { 4., -1., 0. } };
166 
167  // True intersection inside the triangle
168  Geometry::Segment3D seg1{ { 2., 2., 3. }, { 2., 2., -3. } };
169  bool does_seg1_intersect_triangle;
170  vec3 result1;
171  std::tie( does_seg1_intersect_triangle, result1 ) =
172  Intersection::segment_triangle( seg1, triangle );
173  vec3 answer1{ 2., 2., 0. };
174  verdict(
175  does_seg1_intersect_triangle && are_almost_equal( result1, answer1 ),
176  "Test1" );
177 
178  // No intersection
179  Geometry::Segment3D seg2{ { 2., 2., 3. }, { 20., 2., -1. } };
180  bool does_seg2_intersect_triangle;
181  std::tie( does_seg2_intersect_triangle, std::ignore ) =
182  Intersection::segment_triangle( seg2, triangle );
183  verdict( !does_seg2_intersect_triangle, "Test2" );
184 
185  // Intersection at a triangle vertex
186  Geometry::Segment3D seg3{ { 1., 4., 3. }, { 3., 2., -3. } };
187  bool does_seg3_intersect_triangle;
188  vec3 result3;
189  std::tie( does_seg3_intersect_triangle, result3 ) =
190  Intersection::segment_triangle( seg3, triangle );
191  vec3 answer3{ triangle.p1 };
192  verdict(
193  does_seg3_intersect_triangle && are_almost_equal( result3, answer3 ),
194  "Test3" );
195 
196  // Intersection on a triangle edge
197  Geometry::Segment3D seg4{ { 1., -4., 3. }, { 4., 4., -3. } };
198  bool does_seg4_intersect_triangle;
199  vec3 result4;
200  std::tie( does_seg4_intersect_triangle, result4 ) =
201  Intersection::segment_triangle( seg4, triangle );
202  vec3 answer4{ 2.5, 0., 0. };
203  verdict(
204  does_seg4_intersect_triangle && are_almost_equal( result4, answer4 ),
205  "Test4" );
206 
207  // Segment included inside the triangle
208  Geometry::Segment3D seg5{ { 2., 2., 0. }, { 3., 1., 0. } };
209  bool does_seg5_intersect_triangle;
210  std::tie( does_seg5_intersect_triangle, std::ignore ) =
211  Intersection::segment_triangle( seg5, triangle );
212  verdict( !does_seg5_intersect_triangle, "Test5" );
213 
214  // Segment is a triangle edge
215  Geometry::Segment3D seg6{ triangle.p0, triangle.p1 };
216  bool does_seg6_intersect_triangle;
217  std::tie( does_seg6_intersect_triangle, std::ignore ) =
218  Intersection::segment_triangle( seg6, triangle );
219  verdict( !does_seg6_intersect_triangle, "Test6" );
220 
221  // Segment in the same plane than triangle, one point inside the other
222  // outside
223  Geometry::Segment3D seg7{ { 2., 2., 0. }, { 4., 1., -0. } };
224  bool does_seg7_intersect_triangle = true;
225  std::tie( does_seg7_intersect_triangle, std::ignore ) =
226  Intersection::segment_triangle( seg7, triangle );
227  verdict( !does_seg7_intersect_triangle, "Test7" );
228 
229  Logger::out( "TEST", " " );
230 }
231 
233 {
234  Logger::out( "TEST", "Test Circle-Plane intersections" );
235  Geometry::Plane plane{ { 0., 0., -2. }, { 3., 1., -1. } };
236 
237  // Circle parallel to the plane
238  Geometry::Circle circle1{ { { 0., 0., 1. }, { 2., 3., 4. } }, 4. };
239  bool does_circle1_intersect_plane;
240  std::tie( does_circle1_intersect_plane, std::ignore ) =
241  Intersection::circle_plane( circle1, plane );
242  verdict( !does_circle1_intersect_plane, "Test circle parallel to plane" );
243 
244  // Circle adjacent to the plane
245  Geometry::Circle circle2{ { { -1., 2., 0. }, { 2., 3., 4. } }, 5. };
246  bool does_circle2_intersect_plane;
247  std::vector< vec3 > results2;
248  std::tie( does_circle2_intersect_plane, results2 ) =
249  Intersection::circle_plane( circle2, plane );
250  vec3 answer2{ 2., 3., -1. };
251  verdict( does_circle2_intersect_plane && results2.size() == 1,
252  "Test circle adjacent to the plane (number of points)" );
253  verdict( are_almost_equal( results2[0], answer2 ),
254  "Test circle adjacent to the plane (intersection coordinates)" );
255 
256  // Circle crossing the plane
257  Geometry::Circle circle3{ { { 1., -1., 0. }, { 2., 3., 0. } }, 2. };
258  bool does_circle3_intersect_plane;
259  std::vector< vec3 > results3;
260  std::tie( does_circle3_intersect_plane, results3 ) =
261  Intersection::circle_plane( circle3, plane );
262  vec3 answer31{ circle3.plane.origin
263  + vec3{ std::sqrt( 2 ) * std::cos( M_PI / 6 ),
264  std::sqrt( 2 ) * std::cos( M_PI / 6 ), -1. } };
265  vec3 answer32{ circle3.plane.origin
266  + vec3{ -std::sqrt( 2 ) * std::cos( M_PI / 6 ),
267  -std::sqrt( 2 ) * std::cos( M_PI / 6 ), -1. } };
268  verdict( does_circle3_intersect_plane && results3.size() == 2,
269  "Test circle crossing the plane (number of points)" );
270  verdict( ( are_almost_equal( results3[0], answer31 )
271  || ( are_almost_equal( results3[0], answer32 ) ) )
272  && ( are_almost_equal( results3[1], answer31 )
273  || ( are_almost_equal( results3[1], answer32 ) ) ),
274  "Test circle crossing the plane (intersection coordinates)" );
275 
276  Logger::out( "TEST", " " );
277 }
278 
280 {
281  Logger::out( "TEST", "Test Disk-Segment intersections" );
282  Geometry::Disk disk{ { { 0., 4., 0. }, { 2., 2., 2. } }, 4. };
283 
284  // Segment in the disk plane
285  Geometry::Segment3D seg1{ { 1., 2., 3. }, { 3., 2., 1. } };
286  bool does_seg1_intersect_disk;
287  std::tie( does_seg1_intersect_disk, std::ignore ) =
288  Intersection::segment_disk( seg1, disk );
289  verdict( !does_seg1_intersect_disk, "Test segment inside disk" );
290 
291  // Segment adjacent to the disk
292  Geometry::Segment3D seg2{ { -2., 0., -2. }, { -2., 4., 4. } };
293  bool does_seg2_intersect_disk;
294  std::tie( does_seg2_intersect_disk, std::ignore ) =
295  Intersection::segment_disk( seg2, disk );
296  verdict( !does_seg2_intersect_disk, "Test segment tangent to the disk" );
297 
298  // Circle crossing the disk
299  Geometry::Segment3D seg3{ { 1., 1., 3. }, { 3., 3., 1. } };
300  bool does_seg3_intersect_disk;
301  vec3 result3;
302  std::tie( does_seg3_intersect_disk, result3 ) =
303  Intersection::segment_disk( seg3, disk );
304  verdict( does_seg3_intersect_disk,
305  "Test circle adjacent to the plane (intersection exists)" );
306  vec3 answer3{ 2., 2., 2. };
307  verdict( are_almost_equal( result3, answer3 ),
308  "Test circle adjacent to the plane (intersection coordinates)" );
309 
310  Logger::out( "TEST", " " );
311 }
312 
314 {
315  Logger::out( "TEST", "Test Circle-Triangle intersections" );
316  Geometry::Triangle3D triangle{ { 1., 1., 0. }, { 2., 3., 0. },
317  { 4., -1., 0. } };
318 
319  // The circle is (almost) adjacent to the triangle plane on a triangle
320  // border
321  Geometry::Circle circle1{ { { 1., 1., 0. }, { 1.5, 2., 4. } }, 4. };
322  bool does_circle1_intersect_triangle;
323  std::vector< vec3 > results1;
324  std::tie( does_circle1_intersect_triangle, results1 ) =
325  Intersection::triangle_circle( triangle, circle1 );
326  verdict( !does_circle1_intersect_triangle, "Test1 (number of points)" );
327 
328  // One point inside triangle the other one outside
329  Geometry::Circle circle2{ { { 1., 1., 0. }, { 2., 2., 0. } }, 1. };
330  bool does_circle2_intersect_triangle;
331  std::vector< vec3 > results2;
332  std::tie( does_circle2_intersect_triangle, results2 ) =
333  Intersection::triangle_circle( triangle, circle2 );
334  vec3 answer2{ 2. + 0.5 * std::sqrt( 2. ), 2. - 0.5 * std::sqrt( 2. ), 0. };
335  verdict( does_circle2_intersect_triangle && results2.size() == 1,
336  "Test2 (number of points)" );
337  verdict( are_almost_equal( results2[0], answer2 ),
338  "Test2 (intersection coordinates)" );
339 
340  // The circle is (almost) adjacent to the triangle plane on a triangle
341  // vertex
342  Geometry::Circle circle3{ { { 1., 1., 0. }, { 1., 1., 4. } }, 4. };
343  bool does_circle3_intersect_triangle;
344  std::vector< vec3 > results3;
345  std::tie( does_circle3_intersect_triangle, results3 ) =
346  Intersection::triangle_circle( triangle, circle3 );
347  verdict( !does_circle3_intersect_triangle, "Test3 (number of points)" );
348 
349  Logger::out( "TEST", " " );
350 }
351 
353 {
354  Logger::out( "TEST", "Test Plane-Plane intersections" );
355  Geometry::Plane plane0{ { 1., -2., 4. }, { 4., -2., 0. } };
356 
357  // Two parallel planes
358  Geometry::Plane plane1{ { -2., 4., -8. }, { 6., 0., 1.52 } };
359  bool does_P1_intersect_plane;
360  std::tie( does_P1_intersect_plane, std::ignore ) =
361  Intersection::plane_plane( plane0, plane1 );
362  verdict( !does_P1_intersect_plane, "Test parallel planes" );
363 
364  // Two times the same plane
365  Geometry::Plane plane2{ { -1., 2., -4. }, { 4., -2., 0. } };
366  bool does_P2_intersect_plane;
367  std::tie( does_P2_intersect_plane, std::ignore ) =
368  Intersection::plane_plane( plane0, plane2 );
369  verdict( !does_P2_intersect_plane, "Test same plane" );
370 
371  // Two intersecting plane
372  Geometry::Plane plane3{ { 0., 2., -4. }, { -3., -1., 1. } };
373  bool does_P3_intersect_plane;
374  Geometry::Line3D result3;
375  std::tie( does_P3_intersect_plane, result3 ) =
376  Intersection::plane_plane( plane0, plane3 );
377  vec3 O_inter_answer3{ 2., -3., 0. };
378  vec3 D_inter_answer3{ 0., 2., 1. };
379  verdict( does_P3_intersect_plane
380  && are_almost_equal(
381  normalize( D_inter_answer3 ), result3.direction )
382  && are_almost_equal( normalize( D_inter_answer3 ),
383  normalize( result3.origin - O_inter_answer3 ) ),
384  "Test intersecting planes" );
385  Logger::out( "TEST", " " );
386 }
387 
389 {
390  Logger::out( "TEST", "Test Line-Line intersections" );
391  Geometry::Line2D line{ { 1.5, 1.5 }, { 0., 0. } };
392 
393  // Two parallel lines
394  Geometry::Line2D line_parallel{ { 1.5, 1.5 }, { 1., 1. } };
395  bool does_parallel_lines_intersect;
396  std::tie( does_parallel_lines_intersect, std::ignore ) =
397  Intersection::line_line( line, line_parallel );
398  verdict( !does_parallel_lines_intersect, "Test parallel lines" );
399 
400  // Two times the same line
401  Geometry::Line2D Line_same{ { -2.5, -2.5 }, { 0., 0. } };
402  bool does_same_lines_intersect;
403  std::tie( does_same_lines_intersect, std::ignore ) =
404  Intersection::line_line( line, Line_same );
405  verdict( !does_same_lines_intersect, "Test same line" );
406 
407  // Two intersecting lines
408  Geometry::Line2D Line_inter{ { 2.5, -2.5 }, { 2., 0. } };
409  bool does_line_intersect_line;
410  vec2 result_inter;
411  vec2 result_answer{ 1., 1. };
412  std::tie( does_line_intersect_line, result_inter ) =
413  Intersection::line_line( line, Line_inter );
414  verdict( does_line_intersect_line
415  && are_almost_equal( result_inter, result_answer ),
416  "Test intersecting lines" );
417 
418  Logger::out( "TEST", " " );
419 }
420 
422 {
423  Logger::out( "TEST", "Test Segment-Segment intersections" );
424  Geometry::Segment2D segment{ { 0., 0. }, { 1.5, 1.5 } };
425 
426  // Two non-intersecting segments
427  Geometry::Segment2D segment1{ { 2., 2. }, { 3., 2. } };
428  bool do_segments_intersect;
429  std::tie( do_segments_intersect, std::ignore ) =
430  Intersection::segment_segment( segment, segment1 );
431  verdict( !do_segments_intersect, "Test non-intersecting segments" );
432 
433  // Two times the same segment
434  std::tie( do_segments_intersect, std::ignore ) =
435  Intersection::segment_segment( segment, segment );
436  verdict( !do_segments_intersect, "Test same segment" );
437 
438  // Two intersecting segments
439  Geometry::Segment2D segment_inter{ { 2., 0. }, { 0., 2. } };
440  vec2 result_inter;
441  std::tie( do_segments_intersect, result_inter ) =
442  Intersection::segment_segment( segment, segment_inter );
443  vec2 result_answer{ 1., 1. };
444  verdict( do_segments_intersect
445  && are_almost_equal( result_inter, result_answer ),
446  "Test intersecting segments" );
447 
448  // Two intersecting segments from same origin
449  Geometry::Segment2D segment_inter2{ { 0., 0. }, { 2., 0. } };
450  vec2 result_inter2;
451  std::tie( do_segments_intersect, result_inter2 ) =
452  Intersection::segment_segment( segment, segment_inter2 );
453  vec2 result_answer2{ 0., 0. };
454  verdict( do_segments_intersect
455  && are_almost_equal( result_inter2, result_answer2 ),
456  "Test intersecting segments from same origin" );
457 
458  // Two intersecting segments at extremity
459  Geometry::Segment2D segment_inter3{ { 0., 0. }, { 1., 1. } };
460  vec2 result_inter3;
461  std::tie( do_segments_intersect, result_inter3 ) =
462  Intersection::segment_segment( segment_inter, segment_inter3 );
463  vec2 result_answer3{ 1., 1. };
464  verdict( do_segments_intersect
465  && are_almost_equal( result_inter3, result_answer3 ),
466  "Test intersecting segments at one extremity" );
467 
468  Logger::out( "TEST", " " );
469 }
470 
472 {
473  Logger::out( "TEST", "Test Segment-Line intersections" );
474  Geometry::Segment2D segment{ { 0., 0. }, { 1.5, 1.5 } };
475 
476  // non-intersecting
477  Geometry::Line2D line{ { 0., 2. }, { 2., 2. } };
478  bool does_segment_intersect_line;
479  std::tie( does_segment_intersect_line, std::ignore ) =
480  Intersection::segment_line( segment, line );
481  verdict( !does_segment_intersect_line, "Test non-intersecting" );
482 
483  // Segment is on the line
484  Geometry::Line2D line_same{ { -1., -1. }, { 1.5, 1.5 } };
485  std::tie( does_segment_intersect_line, std::ignore ) =
486  Intersection::segment_line( segment, line_same );
487  verdict( !does_segment_intersect_line, "Test segment on line" );
488 
489  // intersecting
490  Geometry::Segment2D segment_inter{ { 0., 0. }, { 2., 2. } };
491  Geometry::Line2D line_inter{ { -0.5, 0.5 }, { 2., 0. } };
492  vec2 result_inter;
493  std::tie( does_segment_intersect_line, result_inter ) =
494  Intersection::segment_line( segment_inter, line_inter );
495  vec2 result_answer{ 1., 1. };
496  verdict( does_segment_intersect_line
497  && are_almost_equal( result_inter, result_answer ),
498  "Test intersecting" );
499 
500  // intersecting from same origin
501  Geometry::Line2D line_inter2{ { 0., 1. }, { 0., 0. } };
502  vec2 result_inter2;
503  std::tie( does_segment_intersect_line, result_inter2 ) =
504  Intersection::segment_line( segment, line_inter2 );
505  vec2 result_answer2{ 0., 0. };
506  verdict( does_segment_intersect_line
507  && are_almost_equal( result_inter2, result_answer2 ),
508  "Test intersecting from same origin" );
509 
510  // intersecting segments at extremity
511  Geometry::Segment2D segment_inter3{ { 0., 0. }, { 1., 1. } };
512  Geometry::Line2D line_inter3{ { -0.5, 0.5 }, { 0., 2. } };
513  vec2 result_inter3;
514  std::tie( does_segment_intersect_line, result_inter3 ) =
515  Intersection::segment_line( segment_inter3, line_inter3 );
516  vec2 result_answer3{ 1., 1. };
517  verdict( does_segment_intersect_line
518  && are_almost_equal( result_inter3, result_answer3 ),
519  "Test intersecting segments at one extremity" );
520 
521  Logger::out( "TEST", " " );
522 }
523 
525 {
526  Logger::out( "TEST", "Test Line-Sphere intersections" );
527  Geometry::Sphere sphere{ { 2., 2., 2. }, 4. };
528 
529  // Line outside the sphere
530  Geometry::Line3D line_outside{ { -3., 2., 1. }, { 10., 10., 10. } };
531  bool line_outside_intersect_sphere;
532  std::tie( line_outside_intersect_sphere, std::ignore ) =
533  Intersection::line_sphere( line_outside, sphere );
534  verdict( !line_outside_intersect_sphere, "Test line outside sphere" );
535 
536  // Line tangent to the sphere
537  Geometry::Line3D line_tangent{ { 0., 1., 1. }, { -2., 5., 5. } };
538  bool line_tangent_intersect_sphere;
539  std::vector< vec3 > tangent_result;
540  std::tie( line_tangent_intersect_sphere, tangent_result ) =
541  Intersection::line_sphere( line_tangent, sphere );
542  verdict( tangent_result.size() == 1, "Test line tangent to the sphere" );
543  vec3 tangent_answer{ -2., 2., 2. };
544  verdict( are_almost_equal( tangent_result.front(), tangent_answer ),
545  "Test line tangent to the sphere (intersection coordinates)" );
546 
547  // Line crossing the sphere
548  Geometry::Line3D line_cross{ { 3., 0., 0. }, { 0., 2., 2. } };
549  bool line_cross_intersect_sphere;
550  std::vector< vec3 > cross_result;
551  std::tie( line_cross_intersect_sphere, cross_result ) =
552  Intersection::line_sphere( line_cross, sphere );
553  verdict( cross_result.size() == 2,
554  "Test line crossing the sphere (intersection exists)" );
555  vec3 answer_cross0{ -2., 2., 2. };
556  vec3 answer_cross1{ 6., 2., 2. };
557  verdict( are_almost_equal( cross_result.front(), answer_cross0 ),
558  "Test line crossing the sphere (intersection coordinates)" );
559  verdict( are_almost_equal( cross_result.back(), answer_cross1 ),
560  "Test line crossing the sphere (intersection coordinates)" );
561 
562  Logger::out( "TEST", " " );
563 }
564 
566 {
567  Logger::out( "TEST", "Test Segment-Sphere intersections" );
568  Geometry::Sphere sphere{ { 2., 2., 2. }, 4. };
569 
570  // Segment outside the sphere
571  Geometry::Segment3D seg_outside{ { 10., 10., 10. }, { 15., 20., 10. } };
572  bool segment_outside_intersect_sphere;
573  std::tie( segment_outside_intersect_sphere, std::ignore ) =
574  Intersection::segment_sphere( seg_outside, sphere );
575  verdict( !segment_outside_intersect_sphere, "Test segment outside sphere" );
576 
577  // Segment tangent to the sphere
578  Geometry::Segment3D seg_tangent{ { -2., 5., 5. }, { -2., -5., -5. } };
579  bool segment_tangent_intersect_sphere;
580  std::vector< vec3 > tangent_result;
581  std::tie( segment_tangent_intersect_sphere, tangent_result ) =
582  Intersection::segment_sphere( seg_tangent, sphere );
583  verdict( tangent_result.size() == 1, "Test segment tangent to the sphere" );
584  vec3 tangent_answer{ -2., 2., 2. };
585  verdict( are_almost_equal( tangent_result.front(), tangent_answer ),
586  "Test segment tangent to the sphere (intersection coordinates)" );
587 
588  // Segment crossing the sphere
589  Geometry::Segment3D seg_cross{ { -10., 2., 2. }, { 10., 2., 2. } };
590  bool segment_cross_intersect_sphere;
591  std::vector< vec3 > cross_result;
592  std::tie( segment_cross_intersect_sphere, cross_result ) =
593  Intersection::segment_sphere( seg_cross, sphere );
594  verdict( cross_result.size() == 2,
595  "Test segment crossing the sphere (2 intersections)" );
596  vec3 answer_cross0{ -2., 2., 2. };
597  vec3 answer_cross1{ 6., 2., 2. };
598  verdict( are_almost_equal( cross_result.front(), answer_cross0 ),
599  "Test segment crossing the sphere (intersection coordinates)" );
600  verdict( are_almost_equal( cross_result.back(), answer_cross1 ),
601  "Test segment crossing the sphere (intersection coordinates)" );
602 
603  // Segment crossing the sphere
604  Geometry::Segment3D seg_cross2{ { 2., 3., 2. }, { 2., 8., 2. } };
605  bool segment_cross_intersect_sphere2;
606  std::vector< vec3 > cross_result2;
607  std::tie( segment_cross_intersect_sphere2, cross_result2 ) =
608  Intersection::segment_sphere( seg_cross2, sphere );
609  verdict( cross_result2.size() == 1,
610  "Test segment crossing the sphere (1 intersection)" );
611  vec3 answer_cross3{ 2., 6., 2. };
612  verdict( are_almost_equal( cross_result2.front(), answer_cross3 ),
613  "Test segment crossing the sphere (intersection coordinates)" );
614 
615  Logger::out( "TEST", " " );
616 }
617 
618 int main()
619 {
620  try
621  {
623 
624  Logger::out( "TEST", "Test intersection algorithms" );
625 
638  }
639  catch( const RINGMeshException& e )
640  {
641  Logger::err( e.category(), e.what() );
642  return 1;
643  }
644  catch( const std::exception& e )
645  {
646  Logger::err( "Exception", e.what() );
647  return 1;
648  }
649  Logger::out( "TEST", "SUCCESS" );
650  return 0;
651 }
GEO::vecng< DIMENSION, double > vecn
Definition: types.h:74
vecn< 3 > vec3
Definition: types.h:76
void test_plane_plane_intersection()
std::tuple< bool, vec3 > RINGMESH_API segment_disk(const Geometry::Segment3D &segment, const Geometry::Disk &disk)
std::tuple< bool, vec2 > RINGMESH_API segment_line(const Geometry::Segment2D &segment, const Geometry::Line2D &line)
vecn< 2 > vec2
Definition: types.h:78
std::tuple< bool, Geometry::Line3D > RINGMESH_API plane_plane(const Geometry::Plane &plane0, const Geometry::Plane &plane1)
void test_line_sphere_intersection()
bool are_almost_equal(const vecn< DIMENSION > &vec0, const vecn< DIMENSION > &vec1)
std::tuple< bool, std::vector< vec3 > > RINGMESH_API line_sphere(const Geometry::Line3D &line, const Geometry::Sphere &sphere)
static void err(const std::string &feature, const Args &... args)
Definition: logger.h:68
void test_segment_triangle_intersection()
static void out(const std::string &feature, const Args &... args)
Definition: logger.h:61
std::tuple< bool, std::vector< vec3 > > RINGMESH_API triangle_circle(const Geometry::Triangle3D &triangle, const Geometry::Circle &circle)
void test_segment_segment_intersection()
std::tuple< bool, vec3 > RINGMESH_API segment_plane(const Geometry::Segment3D &segment, const Geometry::Plane &plane)
std::tuple< bool, std::vector< vec3 > > RINGMESH_API segment_sphere(const Geometry::Segment3D &segment, const Geometry::Sphere &sphere)
std::tuple< bool, vec3 > RINGMESH_API segment_triangle(const Geometry::Segment3D &segment, const Geometry::Triangle3D &triangle)
std::tuple< bool, vec2 > RINGMESH_API line_line(const Geometry::Line2D &line0, const Geometry::Line2D &line1)
void test_disk_segment_intersection()
std::tuple< bool, vec2 > RINGMESH_API segment_segment(const Geometry::Segment2D &segment0, const Geometry::Segment2D &segment1)
const std::string & category() const
Definition: common.h:165
void test_line_plane_intersection()
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
void verdict(bool condition, std::string test_name)
void test_segment_line_intersection()
std::tuple< bool, vec3 > RINGMESH_API line_plane(const Geometry::Line3D &line, const Geometry::Plane &plane)
void test_segment_plane_intersection()
std::tuple< bool, std::vector< vec3 > > RINGMESH_API circle_plane(const Geometry::Circle &circle, const Geometry::Plane &plane)
void RINGMESH_API default_configure()
Definition: common.cpp:99
void test_line_line_intersection()
void test_segment_sphere_intersection()
void test_circle_plane_intersection()
void test_circle_triangle_intersection()