BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Triangle_3_Triangle_3_do_intersect.h
Go to the documentation of this file.
00001 // Copyright (c) 2003  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Intersections_3/include/CGAL/Triangle_3_Triangle_3_do_intersect.h $
00016 // $Id: Triangle_3_Triangle_3_do_intersect.h 45156 2008-08-26 13:40:26Z spion $
00017 // 
00018 //
00019 // Author(s)     : Philippe Guigue
00020 
00021 #ifndef CGAL_TRIANGLE_3_TRIANGLE_3_DO_INTERSECT_H
00022 #define CGAL_TRIANGLE_3_TRIANGLE_3_DO_INTERSECT_H
00023 
00024 #include <CGAL/Uncertain.h>
00025 
00026 CGAL_BEGIN_NAMESPACE
00027 
00028 namespace CGALi {
00029 
00030 template <class K>
00031 bool  _intersection_test_vertex(const typename K::Point_3 * p, 
00032                                 const typename K::Point_3 * q, 
00033                                 const typename K::Point_3 * r,
00034                                 const typename K::Point_3 * a, 
00035                                 const typename K::Point_3 * b, 
00036                                 const typename K::Point_3 * c,
00037                                 const K & k){
00038 
00039   CGAL_kernel_precondition( k.coplanar_orientation_3_object() (*p,*q,*r)
00040                             == POSITIVE);
00041   CGAL_kernel_precondition( k.coplanar_orientation_3_object() (*a,*b,*c)
00042                             == POSITIVE);
00043   
00044 
00045   // Vertex p sees vertex c
00046 
00047   typename K::Coplanar_orientation_3 coplanar_orientation = 
00048     k.coplanar_orientation_3_object();
00049 
00050 
00051   if (coplanar_orientation(*c,*a,*q) != NEGATIVE) {
00052     if (coplanar_orientation(*c,*b,*q) != POSITIVE) {
00053       if (coplanar_orientation(*p,*a,*q) == POSITIVE) 
00054         return  coplanar_orientation(*p,*b,*q) != POSITIVE;  
00055       
00056       return coplanar_orientation(*p,*a,*r) != NEGATIVE
00057         && coplanar_orientation(*q,*r,*a) != NEGATIVE;
00058     }
00059      
00060     if (coplanar_orientation(*p,*b,*q) != POSITIVE)
00061       return coplanar_orientation(*c,*b,*r) != POSITIVE
00062         && coplanar_orientation(*q,*r,*b) != NEGATIVE;
00063     return false;
00064     
00065   }
00066   
00067   if (coplanar_orientation(*c,*a,*r) != NEGATIVE) { //qr straddles (ac) 
00068     if (coplanar_orientation(*q,*r,*c) != NEGATIVE)
00069       return (coplanar_orientation(*p,*a,*r) != NEGATIVE);
00070     
00071     return coplanar_orientation(*q,*r,*b) != NEGATIVE
00072       && coplanar_orientation(*c,*r,*b) != NEGATIVE;
00073   }
00074   return false; // ca separes
00075   
00076 }
00077 
00078 
00079 template <class K>
00080 bool  _intersection_test_edge(const typename K::Point_3 * p, 
00081                               const typename K::Point_3 * q, 
00082                               const typename K::Point_3 * r,
00083                               const typename K::Point_3 * a, 
00084                               const typename K::Point_3 * CGAL_kernel_precondition_code(b), 
00085                               const typename K::Point_3 * c,
00086                               const K & k){
00087   
00088   CGAL_kernel_precondition( k.coplanar_orientation_3_object() (*p,*q,*r)
00089                             == POSITIVE);
00090   CGAL_kernel_precondition( k.coplanar_orientation_3_object() (*a,*b,*c)
00091                             == POSITIVE);
00092 
00093   // Vertex p sees edge ca
00094   
00095   typename K::Coplanar_orientation_3 coplanar_orientation = 
00096     k.coplanar_orientation_3_object();
00097 
00098 
00099 
00100   if (coplanar_orientation(*c,*a,*q) != NEGATIVE) {  //pq straddles (ac)
00101     if (coplanar_orientation(*p,*a,*q) != NEGATIVE) 
00102       return coplanar_orientation(*p,*q,*c) != NEGATIVE ;
00103    
00104     return coplanar_orientation(*q,*r,*a) != NEGATIVE
00105       && coplanar_orientation(*r,*p,*a) != NEGATIVE;
00106   }
00107    
00108   if (coplanar_orientation(*c,*a,*r) != NEGATIVE) { 
00109     // pr and qr straddle line (pr)
00110     return coplanar_orientation(*p,*a,*r) != NEGATIVE
00111       && ( coplanar_orientation(*p,*r,*c) != NEGATIVE
00112            || coplanar_orientation(*q,*r,*c) != NEGATIVE );
00113   }
00114     
00115   return false; //ac separes
00116 }
00117 
00118 
00119 template <class K>
00120 bool do_intersect_coplanar(const typename K::Triangle_3 &t1, 
00121                            const typename K::Triangle_3 &t2,
00122                            const K & k) 
00123 {
00124     
00125   CGAL_kernel_precondition( ! k.is_degenerate_3_object() (t1) );
00126   CGAL_kernel_precondition( ! k.is_degenerate_3_object() (t2) );
00127 
00128   typedef typename K::Point_3 Point_3;
00129   
00130   typename K::Construct_vertex_3 vertex_on =
00131     k.construct_vertex_3_object();
00132  
00133   typename K::Coplanar_orientation_3 coplanar_orientation = 
00134     k.coplanar_orientation_3_object();
00135 
00136     const Point_3 & P = vertex_on(t1,0);
00137     const Point_3 & Q = vertex_on(t1,1);
00138     const Point_3 & R = vertex_on(t1,2);
00139     
00140     const Point_3 & A = vertex_on(t2,0);
00141     const Point_3 & B = vertex_on(t2,1);
00142     const Point_3 & C = vertex_on(t2,2);
00143     
00144 
00145     const Point_3 * p = &P;
00146     const Point_3 * q = &Q;
00147     const Point_3 * r = &R;
00148     
00149     const Point_3 * a = &A;
00150     const Point_3 * b = &B;
00151     const Point_3 * c = &C;
00152 
00153     // First we ensure that both triangles are counterclockwise
00154     // oriented, t1 and t2 are supposed  to be non flat.
00155     
00156     if ( coplanar_orientation(P,Q,R) == NEGATIVE ) {
00157       q = &R;
00158       r = &Q;
00159     }
00160     
00161     if ( coplanar_orientation(A,B,C) == NEGATIVE ) {
00162       b = &C;
00163       c = &B;
00164     }
00165 
00166 
00167     // Localization of p in the arrangement of the 
00168     // lines supporting abc's edges
00169 
00170     if ( coplanar_orientation(*a,*b,*p) != NEGATIVE ) {
00171       if ( coplanar_orientation(*b,*c,*p) != NEGATIVE ) {
00172         if ( coplanar_orientation(*c,*a,*p) != NEGATIVE )
00173           // p is inside triangle abc
00174           return true;
00175         // p sees ac
00176         return CGALi::_intersection_test_edge(p,q,r,a,b,c,k);
00177       }
00178       if ( coplanar_orientation(*c,*a,*p) != NEGATIVE )//p sees bc 
00179         return CGALi::_intersection_test_edge(p,q,r,c,a,b,k);
00180       // p sees c
00181       return CGALi::_intersection_test_vertex(p,q,r,a,b,c,k);
00182       
00183     }
00184     if ( coplanar_orientation(*b,*c,*p) != NEGATIVE ) {
00185       if ( coplanar_orientation(*c,*a,*p) != NEGATIVE ) //p sees ab
00186         return CGALi::_intersection_test_edge(p,q,r,b,c,a,k);
00187       // p sees a
00188       return CGALi::_intersection_test_vertex(p,q,r,b,c,a,k);
00189     } 
00190     // p sees b
00191     return CGALi::_intersection_test_vertex(p,q,r,c,a,b,k);
00192     
00193 }
00194 
00195 
00196 template <class K>
00197 typename K::Boolean
00198 do_intersect(const typename K::Triangle_3 &t1, 
00199              const typename K::Triangle_3 &t2,
00200              const K & k) 
00201 {
00202   CGAL_kernel_precondition( ! k.is_degenerate_3_object() (t1) );
00203   CGAL_kernel_precondition( ! k.is_degenerate_3_object() (t2) );
00204 
00205   typedef typename K::Point_3 Point_3;
00206 
00207   typename K::Construct_vertex_3 vertex_on =
00208     k.construct_vertex_3_object();
00209 
00210   typename K::Orientation_3 orientation = 
00211     k.orientation_3_object();
00212 
00213 
00214    const Point_3 & p = vertex_on(t1,0);
00215    const Point_3 & q = vertex_on(t1,1);
00216    const Point_3 & r = vertex_on(t1,2);
00217    const Point_3 & a = vertex_on(t2,0);
00218    const Point_3 & b = vertex_on(t2,1);
00219    const Point_3 & c = vertex_on(t2,2);
00220 
00221 
00222    const Point_3  * s_min1;
00223    const Point_3  * t_min1;
00224    const Point_3  * s_max1;
00225    const Point_3  * t_max1;
00226    
00227    // Compute distance signs  of p, q and r to the plane of triangle(a,b,c)
00228    const Orientation dp = make_certain(orientation(a,b,c,p));
00229    const Orientation dq = make_certain(orientation(a,b,c,q));
00230    const Orientation dr = make_certain(orientation(a,b,c,r));
00231    
00232  
00233     switch ( dp ) {
00234     case POSITIVE:
00235       if ( dq == POSITIVE ) {
00236         if ( dr == POSITIVE) 
00237           // pqr lies in the open positive halfspace induced by
00238           // the plane of triangle(a,b,c)
00239           return false;
00240         // r is isolated on the negative side of the plane
00241         s_min1 = &q ; t_min1 = &r ; s_max1 = &r ; t_max1 = &p; 
00242         
00243       } else {
00244         if  ( dr == POSITIVE) {
00245           // q is isolated on the negative side of the plane
00246           s_min1 =  &p; t_min1 =  &q; s_max1 =  &q; t_max1 =  &r; 
00247         } else {
00248           // p is isolated on the positive side of the plane
00249           s_min1 =  &p; t_min1 =  &q; s_max1 =  &r; t_max1 =  &p; 
00250         }
00251       }
00252       break;
00253       
00254     case NEGATIVE:
00255       if ( dq == NEGATIVE ) {
00256         if ( dr == NEGATIVE ) 
00257           // pqr lies in the open negative halfspace induced by
00258           // the plane of triangle(a,b,c)
00259           return false; 
00260         // r is isolated on the positive side of the plane
00261         s_min1 =  &r; t_min1 =  &p; s_max1 =  &q; t_max1 =  &r; 
00262         
00263       } else {
00264         if ( dr == NEGATIVE ) {
00265           // q is isolated on the positive side of the plane
00266           s_min1 =  &q; t_min1 =  &r; s_max1 =  &p; t_max1 =  &q; 
00267         } else {
00268           // p is isolated on the negative side of the plane
00269           s_min1 =  &r; t_min1 =  &p; s_max1 =  &p; t_max1 =  &q; 
00270         }
00271       }
00272       break;
00273       
00274     case COPLANAR:
00275       switch  ( dq ) {
00276       case POSITIVE:
00277         if ( dr == POSITIVE ) {
00278           // p is isolated on the negative side of the plane
00279           s_min1 =  &r; t_min1 =  &p; s_max1 =  &p; t_max1 =  &q; 
00280         } else {
00281           // q is isolated on the positive side of the plane
00282           s_min1 =  &q; t_min1 =  &r; s_max1 =  &p; t_max1 =  &q; 
00283         }
00284         break;
00285         
00286       case NEGATIVE:
00287         if ( dr == NEGATIVE ) {
00288           // p is isolated on the positive side of the plane
00289           s_min1 =  &p; t_min1 =  &q; s_max1 =  &r; t_max1 =  &p; 
00290         } else {
00291           // q is isolated on the negative side of the plane
00292           s_min1 =  &p; t_min1 =  &q; s_max1 =  &q; t_max1 =  &r; 
00293         }
00294         break;
00295         
00296       case COPLANAR:
00297         switch ( dr ) {
00298         case POSITIVE:
00299           // r is isolated on the positive side of the plane
00300           s_min1 =  &r; t_min1 =  &p; s_max1 =  &q; t_max1 =  &r; 
00301           break;
00302           
00303         case NEGATIVE:
00304           // r is isolated on the negative side of the plane
00305           s_min1 =  &q ; t_min1 =  &r ; s_max1 =  &r ; t_max1 =  &p; 
00306           break;
00307           
00308         case COPLANAR:
00309           return do_intersect_coplanar(t1,t2,k);
00310         default: // should not happen.
00311           CGAL_kernel_assertion(false);
00312           return false;
00313           
00314         }
00315         break;
00316         
00317       default: // should not happen.
00318       CGAL_kernel_assertion(false);
00319       return false;
00320         
00321       }
00322       break;
00323       
00324     default: // should not happen.
00325       CGAL_kernel_assertion(false);
00326       return false;
00327     }
00328 
00329         
00330     
00331     const Point_3  * s_min2;
00332     const Point_3  * t_min2;
00333     const Point_3  * s_max2;
00334     const Point_3  * t_max2;
00335     
00336     // Compute distance signs  of a, b and c to the plane of triangle(p,q,r)
00337     const Orientation da = make_certain(orientation(p,q,r,a));
00338     const Orientation db = make_certain(orientation(p,q,r,b));
00339     const Orientation dc = make_certain(orientation(p,q,r,c));
00340     
00341 
00342     switch ( da ) {
00343     case POSITIVE:
00344       if ( db == POSITIVE ) {
00345         if ( dc == POSITIVE) 
00346           // abc lies in the open positive halfspace induced by
00347           // the plane of triangle(p,q,r)
00348           return false;
00349         // c is isolated on the negative side of the plane
00350         s_min2 =  &b ; t_min2 =  &c ; s_max2 =  &c ; t_max2 =  &a; 
00351         
00352       } else {
00353         if  ( dc == POSITIVE) {
00354           // b is isolated on the negative side of the plane
00355           s_min2 =  &a; t_min2 =  &b; s_max2 =  &b; t_max2 =  &c; 
00356         } else {
00357           // a is isolated on the positive side of the plane
00358           s_min2 =  &a; t_min2 =  &b; s_max2 =  &c; t_max2 =  &a; 
00359         }
00360       }
00361       break;
00362       
00363     case NEGATIVE:
00364       if ( db == NEGATIVE ) {
00365         if ( dc == NEGATIVE ) 
00366           // abc lies in the open negative halfspace induced by
00367           // the plane of triangle(p,q,r)
00368           return false; 
00369         // c is isolated on the positive side of the plane
00370         s_min2 =  &c ; t_min2 =  &a ; s_max2 =  &b ; t_max2 =  &c; 
00371 
00372       } else {
00373         if ( dc == NEGATIVE ) {
00374           // b is isolated on the positive side of the plane
00375           s_min2 =  &b ; t_min2 =  &c ; s_max2 =  &a ; t_max2 =  &b; 
00376         } else {
00377           // a is isolated on the negative side of the plane
00378           s_min2 =  &c ; t_min2 =  &a ; s_max2 =  &a ; t_max2 =  &b; 
00379         }
00380       }
00381       break;
00382       
00383     case COPLANAR:
00384       switch  ( db ) {
00385       case POSITIVE:
00386         if ( dc == POSITIVE ) {
00387           // a is isolated on the negative side of the plane
00388           s_min2 =  &c ; t_min2 =  &a ; s_max2 =  &a ; t_max2 =  &b; 
00389         } else {
00390           // b is isolated on the positive side of the plane
00391           s_min2 =  &b ; t_min2 =  &c ; s_max2 =  &a ; t_max2 =  &b; 
00392         }
00393         break;
00394         
00395       case NEGATIVE:
00396         if ( dc == NEGATIVE ) {
00397           // a is isolated on the positive side of the plane
00398           s_min2 =  &a ; t_min2 =  &b ; s_max2 =  &c ; t_max2 =  &a; 
00399         } else {
00400           // b is isolated on the negative side of the plane
00401           s_min2 =  &a ; t_min2 =  &b ; s_max2 =  &b ; t_max2 =  &c; 
00402         }
00403         break;
00404         
00405       case COPLANAR:
00406         switch ( dc ) {
00407         case POSITIVE:
00408           // c is isolated on the positive side of the plane
00409           s_min2 =  &c ; t_min2 =  &a ; s_max2 =  &b ; t_max2 =  &c;
00410           break;
00411           
00412         case NEGATIVE:
00413           // c is isolated on the negative side of the plane
00414           s_min2 =  &b ; t_min2 =  &c ; s_max2 =  &c ; t_max2 =  &a; 
00415           break;
00416           
00417         case COPLANAR:
00418           // Supposed unreachable code
00419           // since the triangles are assumed to be non-flat
00420           
00421           return do_intersect_coplanar(t1,t2,k);
00422         default: // should not happen.
00423           CGAL_kernel_assertion(false);
00424           return false;
00425           
00426         }
00427         break;
00428         
00429       default: // should not happen.
00430       CGAL_kernel_assertion(false);
00431       return false;
00432         
00433       }
00434       break;
00435       
00436     default: // should not happen.
00437       CGAL_kernel_assertion(false);
00438       return false;
00439     }
00440     
00441     return  orientation(*s_min1,*t_min1,*s_min2,*t_min2) != POSITIVE 
00442       &&  orientation(*s_max1,*t_max1,*t_max2,*s_max2) != POSITIVE;
00443 }
00444 
00445 } // namespace CGALi
00446 
00447 
00448 template <class K>
00449 inline typename K::Boolean
00450 do_intersect(const Triangle_3<K> &t1, 
00451              const Triangle_3<K> &t2) 
00452 {
00453   return typename K::Do_intersect_3()(t1,t2);
00454 }
00455         
00456 CGAL_END_NAMESPACE
00457 
00458 #endif // CGAL_TRIANGLE_3_TRIANGLE_3_DO_INTERSECT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines