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
This commit is contained in:
Sébastien Loriot 2010-10-28 15:13:53 +00:00
parent e8432b3bb6
commit b2f7df6513
3 changed files with 384 additions and 2 deletions

View File

@ -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<typename K::Line_3> (&res);
if (l!=NULL) return make_object(s);
const typename K::Line_3* l2=object_cast<typename K::Line_3> (&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 <class K>
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 <class K>
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<typename K::Point_3> (&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<typename K::Line_3> (&res);
if (l2!=NULL) return make_object(r);
}
return Object();
}
template <class K>
Object
intersection(const typename K::Ray_3 &r,
const typename K::Line_3 &l,
const K& k)
{
return intersection(l,r,k);
}
template <class K>
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 <class K>
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 <class K>
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<typename K::Point_3> (&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<typename K::Segment_3> (&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 <class K>
Object
intersection(const typename K::Ray_3 &r,
const typename K::Segment_3 &s,
const K& k)
{
return intersection(s,r,k);
}
template <class K>
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 <class K>
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 <class K>
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<typename K::Point_3> (&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<typename K::Ray_3> (&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 <class K>
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 <class K>
Object
intersection(const typename K::Plane_3 &p,
@ -1340,6 +1558,30 @@ intersection(const Line_3<K> &l,
return typename K::Intersect_3()(l, s);
}
template <class K>
inline
Object
intersection(const Line_3<K> &l,
const Ray_3<K> &r) {
return typename K::Intersect_3()(l, r);
}
template <class K>
inline
Object
intersection(const Ray_3<K> &r,
const Segment_3<K> &s) {
return typename K::Intersect_3()(r, s);
}
template <class K>
inline
Object
intersection(const Ray_3<K> &r1,
const Ray_3<K> &r2) {
return typename K::Intersect_3()(r1, r2);
}
template <class K>
inline
bool
@ -1348,6 +1590,30 @@ do_intersect(const Line_3<K> &l, const Segment_3<K> &s)
return typename K::Do_intersect_3()(l, s);
}
template <class K>
inline
bool
do_intersect(const Line_3<K> &l, const Ray_3<K> &r)
{
return typename K::Do_intersect_3()(l, r);
}
template <class K>
inline
bool
do_intersect(const Ray_3<K> &r, const Segment_3<K> &s)
{
return typename K::Do_intersect_3()(r, s);
}
template <class K>
inline
bool
do_intersect(const Ray_3<K> &r1, const Ray_3<K> &r2)
{
return typename K::Do_intersect_3()(r1, r2);
}
template <class K>
inline
Object

View File

@ -262,6 +262,33 @@ intersection(const Segment_3<R> &s,
const Line_3<R> &l)
{return intersection(l,s);}
template <class R>
Object
intersection(const Line_3<R> &,
const Ray_3<R> &);
template <class R>
Object
intersection(const Ray_3<R> &r,
const Line_3<R> &l)
{return intersection(l,r);}
template <class R>
Object
intersection(const Ray_3<R> &,
const Segment_3<R> &);
template <class R>
Object
intersection(const Segment_3<R> &s,
const Ray_3<R> &r)
{return intersection(r,s);}
template <class R>
Object
intersection(const Ray_3<R> &,
const Ray_3<R> &);
template <class R>
Object
intersection(const Sphere_3<R> &s1,
@ -301,6 +328,33 @@ do_intersect(const Segment_3<R> &s,
const Line_3<R> &l)
{return do_intersect(l,s);}
template <class R>
bool
do_intersect(const Line_3<R> &,
const Ray_3<R> &);
template <class R>
bool
do_intersect(const Ray_3<R> &r,
const Line_3<R> &l)
{return do_intersect(l,r);}
template <class R>
bool
do_intersect(const Ray_3<R> &,
const Segment_3<R> &);
template <class R>
bool
do_intersect(const Segment_3<R> &s,
const Ray_3<R> &r)
{return do_intersect(r,s);}
template <class R>
bool
do_intersect(const Ray_3<R> &r1,
const Ray_3<R> &r2);
template <class R>
bool
do_intersect(const Sphere_3<R> &s1,

View File

@ -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();
}
};