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