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