36 #include <ringmesh/ringmesh_tests_config.h> 40 #include <geogram/basic/vecg.h> 50 void verdict(
bool condition, std::string test_name )
62 template < index_t DIMENSION >
66 return ( vec0 - vec1 ).length2() < global_epsilon_sq;
71 Logger::out(
"TEST",
"Test Line-Plane intersections" );
75 Geometry::Line3D line1{ { -2., 4., 1. }, { 1., 5., 0. } };
76 bool does_line1_intersect_plane;
78 std::tie( does_line1_intersect_plane, result1 ) =
80 vec3 answer1{ line1.origin };
81 verdict( does_line1_intersect_plane && result1 == answer1,
82 "True intersection1" );
85 Geometry::Line3D line2{ { -2., 4., 1. }, { -41., 7., -28. } };
86 bool does_line2_intersect_plane;
88 std::tie( does_line2_intersect_plane, result2 ) =
90 vec3 answer2{ 1., -77., -49. };
91 verdict( does_line2_intersect_plane && result2 == answer2,
92 "True intersection2" );
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 ) =
99 verdict( !does_line3_intersect_plane,
"Line parallel to 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 ) =
106 verdict( !does_line4_intersect_plane,
"Line included into the plane" );
113 Logger::out(
"TEST",
"Test Segment-Plane intersections" );
117 Geometry::Segment3D seg1{ { 3., -1., 6.75 }, { -3., -10., -8.25 } };
118 bool does_seg1_intersect_plane;
120 std::tie( does_seg1_intersect_plane, result1 ) =
122 vec3 answer1{ 1., -4., 1.75 };
124 "True intersection" );
127 Geometry::Segment3D seg2{ { 3., -1., 6.75 }, { 1., -4., 1.75 } };
128 bool does_seg2_intersect_plane;
130 std::tie( does_seg2_intersect_plane, result2 ) =
132 vec3 answer2{ seg2.p1 };
134 "Intersection at segment extremity" );
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 ) =
141 verdict( !does_seg3_intersect_plane,
142 "Intersection on line but but into segment" );
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 ) =
149 verdict( !does_seg4_intersect_plane,
"Segment parallel to 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 ) =
156 verdict( !does_seg5_intersect_plane,
"Segment included into the plane" );
163 Logger::out(
"TEST",
"Test Segment-Triangle intersections" );
164 Geometry::Triangle3D triangle{ { 1., 1., 0. }, { 2., 3., 0. },
168 Geometry::Segment3D seg1{ { 2., 2., 3. }, { 2., 2., -3. } };
169 bool does_seg1_intersect_triangle;
171 std::tie( does_seg1_intersect_triangle, result1 ) =
173 vec3 answer1{ 2., 2., 0. };
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 ) =
183 verdict( !does_seg2_intersect_triangle,
"Test2" );
186 Geometry::Segment3D seg3{ { 1., 4., 3. }, { 3., 2., -3. } };
187 bool does_seg3_intersect_triangle;
189 std::tie( does_seg3_intersect_triangle, result3 ) =
191 vec3 answer3{ triangle.p1 };
197 Geometry::Segment3D seg4{ { 1., -4., 3. }, { 4., 4., -3. } };
198 bool does_seg4_intersect_triangle;
200 std::tie( does_seg4_intersect_triangle, result4 ) =
202 vec3 answer4{ 2.5, 0., 0. };
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 ) =
212 verdict( !does_seg5_intersect_triangle,
"Test5" );
215 Geometry::Segment3D seg6{ triangle.p0, triangle.p1 };
216 bool does_seg6_intersect_triangle;
217 std::tie( does_seg6_intersect_triangle, std::ignore ) =
219 verdict( !does_seg6_intersect_triangle,
"Test6" );
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 ) =
227 verdict( !does_seg7_intersect_triangle,
"Test7" );
234 Logger::out(
"TEST",
"Test Circle-Plane intersections" );
239 bool does_circle1_intersect_plane;
240 std::tie( does_circle1_intersect_plane, std::ignore ) =
242 verdict( !does_circle1_intersect_plane,
"Test circle parallel to plane" );
246 bool does_circle2_intersect_plane;
247 std::vector< vec3 > results2;
248 std::tie( does_circle2_intersect_plane, results2 ) =
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)" );
254 "Test circle adjacent to the plane (intersection coordinates)" );
258 bool does_circle3_intersect_plane;
259 std::vector< vec3 > results3;
260 std::tie( does_circle3_intersect_plane, results3 ) =
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)" );
274 "Test circle crossing the plane (intersection coordinates)" );
281 Logger::out(
"TEST",
"Test Disk-Segment intersections" );
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 ) =
289 verdict( !does_seg1_intersect_disk,
"Test segment inside 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 ) =
296 verdict( !does_seg2_intersect_disk,
"Test segment tangent to the disk" );
299 Geometry::Segment3D seg3{ { 1., 1., 3. }, { 3., 3., 1. } };
300 bool does_seg3_intersect_disk;
302 std::tie( does_seg3_intersect_disk, result3 ) =
304 verdict( does_seg3_intersect_disk,
305 "Test circle adjacent to the plane (intersection exists)" );
306 vec3 answer3{ 2., 2., 2. };
308 "Test circle adjacent to the plane (intersection coordinates)" );
315 Logger::out(
"TEST",
"Test Circle-Triangle intersections" );
316 Geometry::Triangle3D triangle{ { 1., 1., 0. }, { 2., 3., 0. },
322 bool does_circle1_intersect_triangle;
323 std::vector< vec3 > results1;
324 std::tie( does_circle1_intersect_triangle, results1 ) =
326 verdict( !does_circle1_intersect_triangle,
"Test1 (number of points)" );
330 bool does_circle2_intersect_triangle;
331 std::vector< vec3 > results2;
332 std::tie( does_circle2_intersect_triangle, results2 ) =
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)" );
338 "Test2 (intersection coordinates)" );
343 bool does_circle3_intersect_triangle;
344 std::vector< vec3 > results3;
345 std::tie( does_circle3_intersect_triangle, results3 ) =
347 verdict( !does_circle3_intersect_triangle,
"Test3 (number of points)" );
354 Logger::out(
"TEST",
"Test Plane-Plane intersections" );
359 bool does_P1_intersect_plane;
360 std::tie( does_P1_intersect_plane, std::ignore ) =
362 verdict( !does_P1_intersect_plane,
"Test parallel planes" );
366 bool does_P2_intersect_plane;
367 std::tie( does_P2_intersect_plane, std::ignore ) =
369 verdict( !does_P2_intersect_plane,
"Test same plane" );
373 bool does_P3_intersect_plane;
374 Geometry::Line3D result3;
375 std::tie( does_P3_intersect_plane, result3 ) =
377 vec3 O_inter_answer3{ 2., -3., 0. };
378 vec3 D_inter_answer3{ 0., 2., 1. };
379 verdict( does_P3_intersect_plane
381 normalize( D_inter_answer3 ), result3.direction )
383 normalize( result3.origin - O_inter_answer3 ) ),
384 "Test intersecting planes" );
390 Logger::out(
"TEST",
"Test Line-Line intersections" );
391 Geometry::Line2D line{ { 1.5, 1.5 }, { 0., 0. } };
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 ) =
398 verdict( !does_parallel_lines_intersect,
"Test parallel lines" );
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 ) =
405 verdict( !does_same_lines_intersect,
"Test same line" );
408 Geometry::Line2D Line_inter{ { 2.5, -2.5 }, { 2., 0. } };
409 bool does_line_intersect_line;
411 vec2 result_answer{ 1., 1. };
412 std::tie( does_line_intersect_line, result_inter ) =
414 verdict( does_line_intersect_line
416 "Test intersecting lines" );
423 Logger::out(
"TEST",
"Test Segment-Segment intersections" );
424 Geometry::Segment2D segment{ { 0., 0. }, { 1.5, 1.5 } };
427 Geometry::Segment2D segment1{ { 2., 2. }, { 3., 2. } };
428 bool do_segments_intersect;
429 std::tie( do_segments_intersect, std::ignore ) =
431 verdict( !do_segments_intersect,
"Test non-intersecting segments" );
434 std::tie( do_segments_intersect, std::ignore ) =
436 verdict( !do_segments_intersect,
"Test same segment" );
439 Geometry::Segment2D segment_inter{ { 2., 0. }, { 0., 2. } };
441 std::tie( do_segments_intersect, result_inter ) =
443 vec2 result_answer{ 1., 1. };
446 "Test intersecting segments" );
449 Geometry::Segment2D segment_inter2{ { 0., 0. }, { 2., 0. } };
451 std::tie( do_segments_intersect, result_inter2 ) =
453 vec2 result_answer2{ 0., 0. };
456 "Test intersecting segments from same origin" );
459 Geometry::Segment2D segment_inter3{ { 0., 0. }, { 1., 1. } };
461 std::tie( do_segments_intersect, result_inter3 ) =
463 vec2 result_answer3{ 1., 1. };
466 "Test intersecting segments at one extremity" );
473 Logger::out(
"TEST",
"Test Segment-Line intersections" );
474 Geometry::Segment2D segment{ { 0., 0. }, { 1.5, 1.5 } };
477 Geometry::Line2D line{ { 0., 2. }, { 2., 2. } };
478 bool does_segment_intersect_line;
479 std::tie( does_segment_intersect_line, std::ignore ) =
481 verdict( !does_segment_intersect_line,
"Test non-intersecting" );
484 Geometry::Line2D line_same{ { -1., -1. }, { 1.5, 1.5 } };
485 std::tie( does_segment_intersect_line, std::ignore ) =
487 verdict( !does_segment_intersect_line,
"Test segment on line" );
490 Geometry::Segment2D segment_inter{ { 0., 0. }, { 2., 2. } };
491 Geometry::Line2D line_inter{ { -0.5, 0.5 }, { 2., 0. } };
493 std::tie( does_segment_intersect_line, result_inter ) =
495 vec2 result_answer{ 1., 1. };
496 verdict( does_segment_intersect_line
498 "Test intersecting" );
501 Geometry::Line2D line_inter2{ { 0., 1. }, { 0., 0. } };
503 std::tie( does_segment_intersect_line, result_inter2 ) =
505 vec2 result_answer2{ 0., 0. };
506 verdict( does_segment_intersect_line
508 "Test intersecting from same origin" );
511 Geometry::Segment2D segment_inter3{ { 0., 0. }, { 1., 1. } };
512 Geometry::Line2D line_inter3{ { -0.5, 0.5 }, { 0., 2. } };
514 std::tie( does_segment_intersect_line, result_inter3 ) =
516 vec2 result_answer3{ 1., 1. };
517 verdict( does_segment_intersect_line
519 "Test intersecting segments at one extremity" );
526 Logger::out(
"TEST",
"Test Line-Sphere intersections" );
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 ) =
534 verdict( !line_outside_intersect_sphere,
"Test line outside 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 ) =
542 verdict( tangent_result.size() == 1,
"Test line tangent to the sphere" );
543 vec3 tangent_answer{ -2., 2., 2. };
545 "Test line tangent to the sphere (intersection coordinates)" );
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 ) =
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. };
558 "Test line crossing the sphere (intersection coordinates)" );
560 "Test line crossing the sphere (intersection coordinates)" );
567 Logger::out(
"TEST",
"Test Segment-Sphere intersections" );
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 ) =
575 verdict( !segment_outside_intersect_sphere,
"Test segment outside 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 ) =
583 verdict( tangent_result.size() == 1,
"Test segment tangent to the sphere" );
584 vec3 tangent_answer{ -2., 2., 2. };
586 "Test segment tangent to the sphere (intersection coordinates)" );
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 ) =
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. };
599 "Test segment crossing the sphere (intersection coordinates)" );
601 "Test segment crossing the sphere (intersection coordinates)" );
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 ) =
609 verdict( cross_result2.size() == 1,
610 "Test segment crossing the sphere (1 intersection)" );
611 vec3 answer_cross3{ 2., 6., 2. };
613 "Test segment crossing the sphere (intersection coordinates)" );
624 Logger::out(
"TEST",
"Test intersection algorithms" );
644 catch(
const std::exception& e )
GEO::vecng< DIMENSION, double > vecn
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)
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)
void test_segment_triangle_intersection()
static void out(const std::string &feature, const Args &... args)
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
void test_line_plane_intersection()
Classes to build GeoModel from various inputs.
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()
void test_line_line_intersection()
void test_segment_sphere_intersection()
void test_circle_plane_intersection()
void test_circle_triangle_intersection()