BWAPI
|
00001 // Copyright (c) 2000 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Intersections_2/include/CGAL/Ray_2_Ray_2_intersection.h $ 00019 // $Id: Ray_2_Ray_2_intersection.h 45230 2008-08-30 10:29:04Z spion $ 00020 // 00021 // 00022 // Author(s) : Geert-Jan Giezeman 00023 00024 00025 #ifndef CGAL_RAY_2_RAY_2_INTERSECTION_H 00026 #define CGAL_RAY_2_RAY_2_INTERSECTION_H 00027 00028 #include <CGAL/Ray_2.h> 00029 #include <CGAL/Segment_2.h> 00030 #include <CGAL/Point_2.h> 00031 #include <CGAL/kernel_assertions.h> 00032 #include <CGAL/number_utils.h> 00033 #include <CGAL/Line_2.h> 00034 #include <CGAL/Line_2_Line_2_intersection.h> 00035 #include <CGAL/Object.h> 00036 00037 00038 CGAL_BEGIN_NAMESPACE 00039 00040 namespace CGALi { 00041 00042 template <class K> 00043 class Ray_2_Ray_2_pair { 00044 public: 00045 enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, RAY}; 00046 Ray_2_Ray_2_pair(typename K::Ray_2 const *ray1, 00047 typename K::Ray_2 const *ray2) 00048 : _ray1(ray1), _ray2(ray2), _known(false) {} 00049 00050 Intersection_results intersection_type() const; 00051 00052 typename K::Point_2 intersection_point() const; 00053 typename K::Segment_2 intersection_segment() const; 00054 typename K::Ray_2 intersection_ray() const; 00055 protected: 00056 typename K::Ray_2 const* _ray1; 00057 typename K::Ray_2 const * _ray2; 00058 mutable bool _known; 00059 mutable Intersection_results _result; 00060 mutable typename K::Point_2 _intersection_point, _other_point; 00061 }; 00062 00063 template <class K> 00064 inline bool do_intersect( 00065 const typename K::Ray_2 &p1, 00066 const typename K::Ray_2 &p2, 00067 const K&) 00068 { 00069 typedef Ray_2_Ray_2_pair<K> pair_t; 00070 pair_t pair(&p1, &p2); 00071 return pair.intersection_type() != pair_t::NO_INTERSECTION; 00072 } 00073 00074 00075 00076 template <class K> 00077 typename Ray_2_Ray_2_pair<K>::Intersection_results 00078 Ray_2_Ray_2_pair<K>::intersection_type() const 00079 { 00080 if (_known) 00081 return _result; 00082 // The non const this pointer is used to cast away const. 00083 _known = true; 00084 // if (!do_overlap(_ray1->bbox(), _ray2->bbox())) 00085 // return NO_INTERSECTION; 00086 const typename K::Line_2 &l1 = _ray1->supporting_line(); 00087 const typename K::Line_2 &l2 = _ray2->supporting_line(); 00088 Line_2_Line_2_pair<K> linepair(&l1, &l2); 00089 switch ( linepair.intersection_type()) { 00090 case Line_2_Line_2_pair<K>::NO_INTERSECTION: 00091 _result = NO_INTERSECTION; 00092 return _result; 00093 case Line_2_Line_2_pair<K>::POINT: 00094 _intersection_point = linepair.intersection_point(); 00095 _result = (_ray1->collinear_has_on(_intersection_point) 00096 && _ray2->collinear_has_on(_intersection_point) ) 00097 ? POINT : NO_INTERSECTION; 00098 return _result; 00099 case Line_2_Line_2_pair<K>::LINE: 00100 { 00101 typedef typename K::RT RT; 00102 const typename K::Vector_2 &dir1 = _ray1->direction().to_vector(); 00103 const typename K::Vector_2 &dir2 = _ray2->direction().to_vector(); 00104 if (CGAL_NTS abs(dir1.x()) > CGAL_NTS abs(dir1.y())) { 00105 typedef typename K::FT FT; 00106 if (dir1.x() > FT(0)) { 00107 if (dir2.x() > FT(0)) { 00108 _intersection_point = 00109 (_ray1->source().x() < _ray2->source().x()) 00110 ? _ray2->source() : _ray1->source(); 00111 _result = RAY; 00112 return _result; 00113 } else { 00114 if (_ray1->source().x() > _ray2->source().x()) { 00115 _result = NO_INTERSECTION; 00116 return _result; 00117 } 00118 if (_ray1->source().x() == _ray2->source().x()) { 00119 _intersection_point = _ray1->source(); 00120 _result = POINT; 00121 return _result; 00122 } 00123 _result = SEGMENT; 00124 return _result; 00125 } 00126 } else { 00127 if (dir2.x() < FT(0)) { 00128 _intersection_point = 00129 (_ray1->source().x() > _ray2->source().x()) 00130 ? _ray2->source() : _ray1->source(); 00131 _result = RAY; 00132 return _result; 00133 } else { 00134 if (_ray1->source().x() < _ray2->source().x()) { 00135 _result = NO_INTERSECTION; 00136 return _result; 00137 } 00138 if (_ray1->source().x() == _ray2->source().x()) { 00139 _intersection_point = _ray1->source(); 00140 _result = POINT; 00141 return _result; 00142 } 00143 _result = SEGMENT; 00144 return _result; 00145 } 00146 } 00147 00148 } else { 00149 typedef typename K::FT FT; 00150 if (dir1.y() > FT(0)) { 00151 if (dir2.y() > FT(0)) { 00152 _intersection_point = 00153 (_ray1->source().y() < _ray2->source().y()) 00154 ? _ray2->source() : _ray1->source(); 00155 _result = RAY; 00156 return _result; 00157 } else { 00158 if (_ray1->source().y() > _ray2->source().y()) { 00159 _result = NO_INTERSECTION; 00160 return _result; 00161 } 00162 if (_ray1->source().y() == _ray2->source().y()) { 00163 _intersection_point = _ray1->source(); 00164 _result = POINT; 00165 return _result; 00166 } 00167 _result = SEGMENT; 00168 return _result; 00169 } 00170 } else { 00171 if (dir2.y() < FT(0)) { 00172 _intersection_point = 00173 (_ray1->source().y() > _ray2->source().y()) 00174 ? _ray2->source() : _ray1->source(); 00175 _result = RAY; 00176 return _result; 00177 } else { 00178 if (_ray1->source().y() < _ray2->source().y()) { 00179 _result = NO_INTERSECTION; 00180 return _result; 00181 } 00182 if (_ray1->source().y() == _ray2->source().y()) { 00183 _intersection_point = _ray1->source(); 00184 _result = POINT; 00185 return _result; 00186 } 00187 _result = SEGMENT; 00188 return _result; 00189 } 00190 } 00191 00192 } 00193 } 00194 default: 00195 CGAL_kernel_assertion(false); // should not be reached: 00196 return _result; 00197 } 00198 } 00199 00200 00201 template <class K> 00202 typename K::Point_2 00203 Ray_2_Ray_2_pair<K>::intersection_point() const 00204 { 00205 if (!_known) 00206 intersection_type(); 00207 CGAL_kernel_assertion(_result == POINT); 00208 return _intersection_point; 00209 } 00210 00211 template <class K> 00212 typename K::Segment_2 00213 Ray_2_Ray_2_pair<K>::intersection_segment() const 00214 { 00215 typedef typename K::Segment_2 Segment_2; 00216 if (!_known) 00217 intersection_type(); 00218 CGAL_kernel_assertion(_result == SEGMENT); 00219 return Segment_2(_ray1->source(), _ray2->source()); 00220 } 00221 00222 template <class K> 00223 typename K::Ray_2 00224 Ray_2_Ray_2_pair<K>::intersection_ray() const 00225 { 00226 typedef typename K::Ray_2 Ray_2; 00227 if (!_known) 00228 intersection_type(); 00229 CGAL_kernel_assertion(_result == RAY); 00230 return Ray_2(_intersection_point, _ray1->direction()); 00231 } 00232 00233 00234 00235 template <class K> 00236 Object 00237 intersection(const typename K::Ray_2 &ray1, 00238 const typename K::Ray_2 &ray2, 00239 const K&) 00240 { 00241 typedef Ray_2_Ray_2_pair<K> is_t; 00242 is_t ispair(&ray1, &ray2); 00243 switch (ispair.intersection_type()) { 00244 case is_t::NO_INTERSECTION: 00245 default: 00246 return Object(); 00247 case is_t::POINT: 00248 return make_object(ispair.intersection_point()); 00249 case is_t::SEGMENT: 00250 return make_object(ispair.intersection_segment()); 00251 case is_t::RAY: 00252 return make_object(ispair.intersection_ray()); 00253 } 00254 } 00255 00256 } // namespace CGALi 00257 00258 00259 template <class K> 00260 inline 00261 bool 00262 do_intersect(const Ray_2<K> &ray1, 00263 const Ray_2<K> &ray2) 00264 { 00265 typedef typename K::Do_intersect_2 Do_intersect; 00266 return Do_intersect()(ray1, ray2); 00267 } 00268 00269 template <class K> 00270 Object 00271 intersection(const Ray_2<K> &ray1, 00272 const Ray_2<K> &ray2) 00273 { 00274 typedef typename K::Intersect_2 Intersect; 00275 return Intersect()(ray1, ray2); 00276 } 00277 00278 CGAL_END_NAMESPACE 00279 00280 #endif