BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Triangle_3_Ray_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_Ray_3_do_intersect.h $
00016 // $Id: Triangle_3_Ray_3_do_intersect.h 39776 2007-08-08 15:15:20Z spion $
00017 // 
00018 //
00019 // Author(s)     : Philippe Guigue
00020 
00021 #ifndef CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
00022 #define CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
00023 
00024 CGAL_BEGIN_NAMESPACE
00025 
00026 namespace CGALi {
00027 
00028 template <class K>
00029 bool do_intersect(const typename K::Triangle_3 &t, 
00030                   const typename K::Ray_3 &r,
00031                   const K & k)
00032 {
00033 
00034   CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
00035   CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
00036 
00037   typedef typename K::Point_3 Point_3;
00038 
00039   typename K::Construct_vertex_3 vertex_on =
00040     k.construct_vertex_3_object();
00041   
00042   typename K::Orientation_3 orientation = 
00043     k.orientation_3_object();
00044 
00045 
00046   const Point_3 & a = vertex_on(t,0);
00047   const Point_3 & b = vertex_on(t,1);
00048   const Point_3 & c = vertex_on(t,2);
00049   
00050   typename K::Construct_vector_3  construct_vector =
00051     k.construct_vector_3_object();
00052 
00053   typename K::Construct_ray_3 construct_ray = 
00054     k.construct_ray_3_object();
00055 
00056   typename K::Construct_point_on_3 point_on = 
00057     k.construct_point_on_3_object();
00058 
00059   const Point_3 & p = point_on(r,0);
00060   const Point_3 & q = point_on(r,1);
00061 
00062 
00063   const Orientation ray_direction =
00064     orientation(a,b,c,point_on(construct_ray(a, construct_vector(r)),1));
00065 
00066     if (ray_direction == COPLANAR ) {
00067       if (orientation(a,b,c,p) == COPLANAR) 
00068         return do_intersect_coplanar(t,r,k);
00069       else return false;
00070     }
00071   
00072   const Orientation abcp = orientation(a,b,c,p);
00073 
00074   switch ( abcp ) {
00075   case POSITIVE: 
00076     switch ( ray_direction ) {
00077     case POSITIVE: 
00078       // the ray lies in the positive open halfspaces defined by the
00079       // triangle's supporting plane
00080       return false;
00081       
00082     case NEGATIVE:
00083       // The ray straddles the triangle's plane
00084       // p sees the triangle in counterclockwise order
00085       
00086       return orientation(p,q,a,b) != POSITIVE
00087         && orientation(p,q,b,c) != POSITIVE
00088         && orientation(p,q,c,a) != POSITIVE;
00089       
00090       // case COPLANAR: should not happen
00091       
00092     default: // should not happen.
00093       CGAL_kernel_assertion(false);
00094       return false;
00095     }
00096     
00097   case NEGATIVE:
00098     switch ( ray_direction ) {
00099     case POSITIVE: 
00100       // The ray straddles the triangle's plane
00101       // q sees the triangle in counterclockwise order
00102       
00103       return orientation(q,p,a,b) != POSITIVE
00104         && orientation(q,p,b,c) != POSITIVE
00105         && orientation(q,p,c,a) != POSITIVE;
00106       
00107     case NEGATIVE:
00108       // the ray lies in the negative open halfspaces defined by the
00109       // triangle's supporting plane
00110       return false;
00111       
00112       // case COPLANAR: should not happen
00113       
00114     default: // should not happen.
00115       CGAL_kernel_assertion(false);
00116       return false;
00117     }
00118     
00119   case COPLANAR: // p belongs to the triangle's supporting plane
00120     switch ( ray_direction ) {
00121     case POSITIVE: 
00122       // q sees the triangle in counterclockwise order
00123       return orientation(q,p,a,b) != POSITIVE
00124         && orientation(q,p,b,c) != POSITIVE
00125         && orientation(q,p,c,a) != POSITIVE;
00126       
00127     case NEGATIVE:
00128       // q sees the triangle in clockwise order
00129       return orientation(p,q,a,b) != POSITIVE
00130         && orientation(p,q,b,c) != POSITIVE
00131         && orientation(p,q,c,a) != POSITIVE;
00132       
00133       // case COPLANAR: should not happen
00134       
00135     default: // should not happen.
00136       CGAL_kernel_assertion(false);
00137       return false;
00138     }
00139     
00140   default: // should not happen.
00141     CGAL_kernel_assertion(false);
00142     return false;
00143     
00144   } 
00145 }
00146 
00147 
00148 template <class K>
00149 inline
00150 bool do_intersect(const typename K::Ray_3 &r,
00151                   const typename K::Triangle_3 &t, 
00152                   const K & k)
00153 {
00154   return do_intersect(t,r, k);
00155 }
00156 
00157 
00158 template <class K>
00159 bool do_intersect_coplanar(const typename K::Triangle_3 &t, 
00160                            const typename K::Ray_3      &r,
00161                            const K & k )
00162 {
00163   
00164   CGAL_kernel_precondition( ! k.is_degenerate_3_object()(t) ) ;
00165   CGAL_kernel_precondition( ! k.is_degenerate_3_object()(r) ) ;
00166   
00167   typedef typename K::Point_3 Point_3;
00168   
00169   typename K::Construct_point_on_3 point_on = 
00170     k.construct_point_on_3_object();
00171   
00172   typename K::Construct_vertex_3 vertex_on =
00173     k.construct_vertex_3_object();
00174   
00175   typename K::Coplanar_orientation_3 coplanar_orientation = 
00176     k.coplanar_orientation_3_object();
00177 
00178   
00179   const Point_3 & p = point_on(r,0);
00180   const Point_3 & q = point_on(r,1);
00181   
00182   const Point_3 & A = vertex_on(t,0);
00183   const Point_3 & B = vertex_on(t,1);
00184   const Point_3 & C = vertex_on(t,2);
00185   
00186   
00187   const Point_3 * a = &A;
00188   const Point_3 * b = &B;
00189   const Point_3 * c = &C;
00190   // Determine the orientation of the triangle in the common plane
00191 
00192   if (coplanar_orientation(A,B,C) != POSITIVE)
00193     {
00194       // The triangle is not counterclockwise oriented
00195       // swap two vertices.
00196       b = &C;
00197       c = &B;
00198     }
00199 
00200   // Test whether the ray's supporting line intersects the
00201   // triangle in the common plane
00202   
00203   const Orientation pqa = coplanar_orientation(p,q,*a);
00204   const Orientation pqb = coplanar_orientation(p,q,*b);
00205   const Orientation pqc = coplanar_orientation(p,q,*c);
00206 
00207 
00208   switch ( pqa ) {
00209   case POSITIVE:
00210     switch ( pqb ) {
00211     case POSITIVE:
00212        if (pqc == POSITIVE) 
00213          // the triangle lies in the positive halfspace
00214          // defined by the ray's supporting line.
00215          return false;
00216        // c is isolated on the negative side
00217        return coplanar_orientation(*a,*c,p) != POSITIVE ;
00218        
00219     case NEGATIVE:
00220       if (pqc == POSITIVE) // b is isolated on the negative side
00221         return coplanar_orientation(*c,*b,p) != POSITIVE ;
00222       // a is isolated on the positive side
00223       return coplanar_orientation(*a,*c,p) != POSITIVE ;
00224 
00225     case COLLINEAR:
00226       if (pqc == POSITIVE) // b is isolated on the negative side
00227         return coplanar_orientation(*c,*b,p) != POSITIVE ;
00228       // a is isolated on the positive side
00229       return  coplanar_orientation(*a,*c,p) != POSITIVE ;
00230       
00231     default: // should not happen.
00232       CGAL_kernel_assertion(false);
00233       return false;
00234     }
00235     
00236   case NEGATIVE:
00237     switch ( pqb ) {
00238     case POSITIVE:
00239       if (pqc == POSITIVE)      // a is isolated on the negative side
00240         return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00241       // b is isolated on the positive side
00242       return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00243       
00244     case NEGATIVE:
00245       if (pqc == NEGATIVE)      
00246         // the triangle lies in the negative halfspace
00247         // defined by the ray's supporting line.
00248         return false;
00249       // c is isolated on the positive side
00250       return  coplanar_orientation(*c,*b,p) != POSITIVE ;
00251     case COLLINEAR:
00252       if (pqc == NEGATIVE) // b is isolated on the positive side
00253         return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00254       // a is isolated on the negative side
00255       return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00256       
00257     default: // should not happen.
00258       CGAL_kernel_assertion(false);
00259       return false;
00260     }
00261     
00262   case COLLINEAR:
00263     switch ( pqb ) {
00264     case POSITIVE:
00265       if (pqc == POSITIVE) // a is isolated on the negative side
00266         return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00267       // b is isolated on the positive side
00268       return  coplanar_orientation(*b,*a,p) != POSITIVE ;
00269     case NEGATIVE:
00270       if (pqc == NEGATIVE) // a is isolated on the positive side
00271         return  coplanar_orientation(*a,*c,p) != POSITIVE ;
00272       // b is isolated on the negative side
00273       return  coplanar_orientation(*c,*b,p) != POSITIVE ;
00274 
00275     case COLLINEAR:
00276       if (pqc == POSITIVE) // c is isolated on the positive side
00277         return  coplanar_orientation(*c,*b,p) != POSITIVE ;
00278       // c is isolated on the negative side
00279       return  coplanar_orientation(*a,*c,p) != POSITIVE ;
00280       // case pqc == COLLINEAR is imposiible
00281 
00282     default: // should not happen.
00283       CGAL_kernel_assertion(false);
00284       return false;
00285     }
00286     
00287   default: // should not happen.
00288     CGAL_kernel_assertion(false);
00289     return false;
00290   }
00291 }
00292 
00293 
00294 } // namespace CGALi
00295 
00296 
00297 template <class K>
00298 inline bool do_intersect(const Ray_3<K> &r, 
00299                          const Triangle_3<K> &t)
00300 {
00301   return typename K::Do_intersect_3()(t,r);
00302 }
00303 
00304 template <class K>
00305 inline bool do_intersect(const Triangle_3<K> &t, 
00306                          const Ray_3<K> &r)
00307 {
00308   return typename K::Do_intersect_3()(t,r);
00309 }
00310 
00311 
00312 /*
00313 template <class K>
00314 inline bool do_intersect(const Ray_3<K> &r, 
00315                          const Triangle_3<K> &t,
00316                          const K & k )
00317 {
00318   return CGALi::do_intersect(t,r,k);
00319 }
00320 */
00321 
00322 CGAL_END_NAMESPACE
00323 
00324 #endif // CGAL_TRIANGLE_3_RAY_3_DO_INTERSECT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines