From b2f7df65130f3f95e676f3de072bff3767056ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 28 Oct 2010 15:13:53 +0000 Subject: [PATCH] add do_intersect for Ray_3 vs {Line_3,Segment_3,Ray_3} add intersection for Ray_3 vs {Line_3,Segment_3,Ray_3} append test to the testsuite correct a variable name in line vs segment intersection --- .../Intersections_3/intersection_3_1_impl.h | 270 +++++++++++++++++- .../include/CGAL/intersection_3_1.h | 54 ++++ .../Intersections_3/test_intersections_3.cpp | 62 ++++ 3 files changed, 384 insertions(+), 2 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/intersection_3_1_impl.h index 0b723ee551f..13659e9d47e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/intersection_3_1_impl.h @@ -353,8 +353,8 @@ intersection(const typename K::Line_3 &l, if ( cln_order(s[0],*p,s[1]) ) return res; } else{ - const typename K::Line_3* l=object_cast (&res); - if (l!=NULL) return make_object(s); + const typename K::Line_3* l2=object_cast (&res); + if (l2!=NULL) return make_object(s); } return Object(); } @@ -402,6 +402,224 @@ do_intersect(const typename K::Segment_3 &s, return do_intersect(l,s,k); } +template +bool +Ray_3_has_on_collinear_Point_3( + const typename K::Ray_3 &r, + const typename K::Point_3 &p, + const K& k) +{ + return + k.equal_3_object()(r.source(),p) + || + k.equal_3_object() ( + k.construct_direction_3_object()( k.construct_vector_3_object() (r.source(),p) ), + r.direction() + ); +} + +template +Object +intersection(const typename K::Line_3 &l, + const typename K::Ray_3 &r, + const K& k) +{ + CGAL_precondition(! l.is_degenerate () && ! r.is_degenerate () ); + Object res = intersection(l,r.supporting_line()); + const typename K::Point_3* p=object_cast (&res); + if (p!=NULL){ + if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) return res; + } + else{ + const typename K::Line_3* l2=object_cast (&res); + if (l2!=NULL) return make_object(r); + } + return Object(); +} + +template +Object +intersection(const typename K::Ray_3 &r, + const typename K::Line_3 &l, + const K& k) +{ + return intersection(l,r,k); +} + +template +inline +bool +do_intersect(const typename K::Line_3 &l, + const typename K::Ray_3 &r, + const K & k) +{ + CGAL_precondition(! l.is_degenerate () && ! r.is_degenerate () ); + if ( !do_intersect(l,r.supporting_line()) ) return false; + typename K::Coplanar_orientation_3 pred=k.coplanar_orientation_3_object(); + Orientation p0p1s=pred(l.point(0),l.point(1),r.source()); + if ( p0p1s == COLLINEAR) return true; + Orientation stp0 =pred(r.source(),r.second_point(),l.point(0)); + if ( stp0 == COLLINEAR ) + return Ray_3_has_on_collinear_Point_3(r,l.point(0),k); + return p0p1s!=stp0; +} + +template +inline +bool +do_intersect(const typename K::Ray_3 &r, + const typename K::Line_3 &l, + const K & k) +{ + return do_intersect(l,r,k); +} + +template +Object +intersection(const typename K::Segment_3 &s, + const typename K::Ray_3 &r, + const K& k) +{ + CGAL_precondition(! s.is_degenerate () && ! r.is_degenerate () ); + Object res = intersection(r.supporting_line(),s); + const typename K::Point_3* p=object_cast (&res); + if (p!=NULL){ + if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) return res; + } + else{ + const typename K::Segment_3* s2=object_cast (&res); + if (s2!=NULL){ + bool has_source=Ray_3_has_on_collinear_Point_3(r,s.source(),k); + bool has_target=Ray_3_has_on_collinear_Point_3(r,s.target(),k); + if (has_source){ + if (has_target) + return res; + else + { + if (k.equal_3_object() (r.source(),s.source())) + return make_object(r.source()); + else + return make_object(k.construct_segment_3_object()(r.source(),s.source())); + } + } + else{ + if (has_target){ + if (k.equal_3_object() (r.source(),s.target())) + return make_object(r.source()); + else + return make_object(k.construct_segment_3_object()(r.source(),s.target())); + } + } + } + } + return Object(); +} + +template +Object +intersection(const typename K::Ray_3 &r, + const typename K::Segment_3 &s, + const K& k) +{ + return intersection(s,r,k); +} + +template +inline +bool +do_intersect(const typename K::Segment_3 &s, + const typename K::Ray_3 &r, + const K & k) +{ + CGAL_precondition(! s.is_degenerate () && ! r.is_degenerate () ); + if ( !do_intersect(s,r.supporting_line()) ) return false; + typename K::Coplanar_orientation_3 pred=k.coplanar_orientation_3_object(); + Orientation p0p1s=pred(s.point(0),s.point(1),r.source()); + Orientation stp0 =pred(r.source(),r.second_point(),s.point(0)); + if ( p0p1s == COLLINEAR) //s belongs to the supporting line of p0p1 + { + if ( stp0 == COLLINEAR )//st and p0p1 have the same supporting line + return Ray_3_has_on_collinear_Point_3(r,s.point(0),k) || Ray_3_has_on_collinear_Point_3(r,s.point(1),k); + else + return true; + } + if ( stp0 == COLLINEAR ) + return Ray_3_has_on_collinear_Point_3(r,s.point(0),k); + return p0p1s!=stp0; +} + +template +inline +bool +do_intersect(const typename K::Ray_3 &r, + const typename K::Segment_3 &s, + const K & k) +{ + return do_intersect(s,r,k); +} + +template +Object +intersection(const typename K::Ray_3 &r1, + const typename K::Ray_3 &r2, + const K& k) +{ + CGAL_precondition(! r1.is_degenerate () && ! r2.is_degenerate () ); + Object res = intersection(r1.supporting_line(),r2); + const typename K::Point_3* p=object_cast (&res); + if (p!=NULL){ + if ( Ray_3_has_on_collinear_Point_3(r1,*p,k) ) return res; + } + else{ + const typename K::Ray_3* r=object_cast (&res); + if (r!=NULL){ + bool r1_has_s2=Ray_3_has_on_collinear_Point_3(r1,r2.source(),k); + bool r2_has_s1=Ray_3_has_on_collinear_Point_3(r2,r1.source(),k); + if (r1_has_s2){ + if (r2_has_s1) + { + if (k.equal_3_object()(r1.source(),r2.source())) + return make_object(r1.source()); + else + return make_object(k.construct_segment_3_object()(r1.source(),r2.source())); + } + else + return res; + } + else{ + if (r2_has_s1) + return make_object(r1); + } + } + } + return Object(); +} + +template +inline +bool +do_intersect(const typename K::Ray_3 &r1, + const typename K::Ray_3 &r2, + const K & k) +{ + CGAL_precondition(! r1.is_degenerate () && ! r2.is_degenerate () ); + if ( !do_intersect(r1,r2.supporting_line()) ) return false; + typename K::Coplanar_orientation_3 pred=k.coplanar_orientation_3_object(); + Orientation p0p1s=pred(r1.point(0),r1.point(1),r2.source()); + Orientation stp0 =pred(r2.source(),r2.second_point(),r1.point(0)); + + if ( p0p1s == COLLINEAR){ + if(stp0 == COLLINEAR ) + return Ray_3_has_on_collinear_Point_3(r2,r1.source(),k) || + Ray_3_has_on_collinear_Point_3(r1,r2.source(),k); + else + return true; + } + if(stp0 == COLLINEAR ) + return Ray_3_has_on_collinear_Point_3(r2,r1.point(0),k); + return p0p1s!=stp0; +} + template Object intersection(const typename K::Plane_3 &p, @@ -1340,6 +1558,30 @@ intersection(const Line_3 &l, return typename K::Intersect_3()(l, s); } +template +inline +Object +intersection(const Line_3 &l, + const Ray_3 &r) { + return typename K::Intersect_3()(l, r); +} + +template +inline +Object +intersection(const Ray_3 &r, + const Segment_3 &s) { + return typename K::Intersect_3()(r, s); +} + +template +inline +Object +intersection(const Ray_3 &r1, + const Ray_3 &r2) { + return typename K::Intersect_3()(r1, r2); +} + template inline bool @@ -1348,6 +1590,30 @@ do_intersect(const Line_3 &l, const Segment_3 &s) return typename K::Do_intersect_3()(l, s); } +template +inline +bool +do_intersect(const Line_3 &l, const Ray_3 &r) +{ + return typename K::Do_intersect_3()(l, r); +} + +template +inline +bool +do_intersect(const Ray_3 &r, const Segment_3 &s) +{ + return typename K::Do_intersect_3()(r, s); +} + +template +inline +bool +do_intersect(const Ray_3 &r1, const Ray_3 &r2) +{ + return typename K::Do_intersect_3()(r1, r2); +} + template inline Object diff --git a/Intersections_3/include/CGAL/intersection_3_1.h b/Intersections_3/include/CGAL/intersection_3_1.h index c77e347ddcc..24031bacc42 100644 --- a/Intersections_3/include/CGAL/intersection_3_1.h +++ b/Intersections_3/include/CGAL/intersection_3_1.h @@ -262,6 +262,33 @@ intersection(const Segment_3 &s, const Line_3 &l) {return intersection(l,s);} +template +Object +intersection(const Line_3 &, + const Ray_3 &); + +template +Object +intersection(const Ray_3 &r, + const Line_3 &l) +{return intersection(l,r);} + +template +Object +intersection(const Ray_3 &, + const Segment_3 &); + +template +Object +intersection(const Segment_3 &s, + const Ray_3 &r) +{return intersection(r,s);} + +template +Object +intersection(const Ray_3 &, + const Ray_3 &); + template Object intersection(const Sphere_3 &s1, @@ -301,6 +328,33 @@ do_intersect(const Segment_3 &s, const Line_3 &l) {return do_intersect(l,s);} +template +bool +do_intersect(const Line_3 &, + const Ray_3 &); + +template +bool +do_intersect(const Ray_3 &r, + const Line_3 &l) +{return do_intersect(l,r);} + +template +bool +do_intersect(const Ray_3 &, + const Segment_3 &); + +template +bool +do_intersect(const Segment_3 &s, + const Ray_3 &r) +{return do_intersect(r,s);} + +template +bool +do_intersect(const Ray_3 &r1, + const Ray_3 &r2); + template bool do_intersect(const Sphere_3 &s1, diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 5c6c211ac00..e0a35cb39a4 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -321,6 +321,65 @@ struct Test { check_intersection ( S(P(0,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true); check_intersection ( S(P(-12,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true); } + + void R_L() + { + std::cout << "Ray - Line\n"; + check_intersection (L(P(0,0,0),P(1,0,0)),R(P(3,0,0),P(6,0,0)),R(P(3,0,0),P(6,0,0))); + check_no_intersection (L(P(0,0,0),P(1,0,0)),R(P(3,0,1),P(6,0,1))); + check_intersection (L(P(0,0,0),P(1,0,0)),R(P(3,0,0),P(6,4,0)),P(3,0,0)); + check_intersection (L(P(0,0,0),P(1,0,0)),R(P(0,-2,0),P(0,-1,0)),P(0,0,0)); + check_no_intersection (L(P(0,0,0),P(1,0,0)),R(P(0, 2,0),P(0,4,0))); + check_intersection (L(P(0,0,0),P(1,0,0)),R(P(5,-2,0),P(5,-1,0)),P(5,0,0)); + check_no_intersection (L(P(0,0,0),P(1,0,0)),R(P(6, 2,0),P(5,4,0))); + } + + void R_S() + { + std::cout << "Ray - Segment\n"; + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,-2,0),P(0,-1,0)),P(0,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,-2,0),P(-3,-1,0)),P(-3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,-2,0),P(3,-1,0)),P(3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,0,0),P(0,-1,0)),P(0,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,0,0),P(-3,-1,0)),P(-3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,0,0),P(3,-1,0)),P(3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,-2,0),P(0,0,0)),P(0,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,-2,0),P(-3,0,0)),P(-3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,-2,0),P(3,0,0)),P(3,0,0)); + check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,-1,0),P(0,-2,0))); + check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,-1,0),P(-3,-2,0))); + check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,-1,0),P(3,-2,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-4,0,0),P(-2,0,0)),S(P(-3,0,0),P(3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-4,0,0),P(7,0,0)),S(P(-3,0,0),P(3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,0,0),P(-2,0,0)),S(P(-3,0,0),P(3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,0,0),P(7,0,0)),S(P(-3,0,0),P(3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,0,0),P(-2,0,0)),S(P(0,0,0),P(-3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,0,0),P(2,0,0)),S(P(0,0,0),P(3,0,0))); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-3,0,0),P(-4,0,0)),P(-3,0,0)); + check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,0,0),P(4,0,0)),P(3,0,0)); + check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(4,0,0),P(5,0,0))); + check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(-5,0,0),P(-8,0,0))); + } + + void R_R() + { + std::cout << "Ray - Ray\n"; + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,0,0),P(-1,0,0)),P(0,0,0)); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,0,0),P(0,1,0)),P(0,0,0)); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(5,0,0),P(5,1,0)),P(5,0,0)); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(-1,0,0),P(3,0,0)),R(P(0,0,0),P(1,0,0))); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(2,0,0),P(3,0,0)),R(P(2,0,0),P(6,0,0))); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(2,0,0),P(-3,0,0)),S(P(0,0,0),P(2,0,0)),false); + check_intersection (R(P(2,0,0),P(-3,0,0)),R(P(0,0,0),P(1,0,0)),S(P(2,0,0),P(0,0,0)),false); + check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(-2,0,0),P(-3,0,0))); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(1,0,0),P(1,1,0)),P(1,0,0)); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(1,-1,0),P(1,1,0)),P(1,0,0)); + check_intersection (R(P(0,0,0),P(1,0,0)),R(P(1,-2,0),P(1,-1,0)),P(1,0,0)); + check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(1,-1,0),P(1,-2,0))); + check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,-1,0),P(0,-2,0))); + check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,1,0),P(0,2,0))); + } + void run() { @@ -336,6 +395,9 @@ struct Test { S_Cub(); Pl_Tr(); S_L(); + R_L(); + R_S(); + R_R(); } };