BWAPI
|
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