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_Segment_2_intersection.h $ 00019 // $Id: Ray_2_Segment_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_SEGMENT_2_INTERSECTION_H 00026 #define CGAL_RAY_2_SEGMENT_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 CGAL_BEGIN_NAMESPACE 00038 00039 namespace CGALi { 00040 00041 template <class K> 00042 class Ray_2_Segment_2_pair { 00043 public: 00044 enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; 00045 Ray_2_Segment_2_pair(typename K::Ray_2 const *ray, 00046 typename K::Segment_2 const *seg) 00047 : _ray(ray), _seg(seg), _known(false) {} 00048 00049 Intersection_results intersection_type() const; 00050 00051 typename K::Point_2 intersection_point() const; 00052 typename K::Segment_2 intersection_segment() const; 00053 protected: 00054 typename K::Ray_2 const * _ray; 00055 typename K::Segment_2 const * _seg; 00056 mutable bool _known; 00057 mutable Intersection_results _result; 00058 mutable typename K::Point_2 _intersection_point, _other_point; 00059 }; 00060 00061 template <class K> 00062 inline bool do_intersect(const typename K::Ray_2 &p1, 00063 const typename K::Segment_2 &p2, 00064 const K&) 00065 { 00066 typedef Ray_2_Segment_2_pair<K> pair_t; 00067 pair_t pair(&p1, &p2); 00068 return pair.intersection_type() != pair_t::NO_INTERSECTION; 00069 } 00070 00071 template <class K> 00072 inline bool do_intersect(const typename K::Segment_2 &p2, 00073 const typename K::Ray_2 &p1, 00074 const K& k) 00075 { 00076 return CGALi::do_intersect(p1, p2, k); 00077 } 00078 00079 template <class K> 00080 typename Ray_2_Segment_2_pair<K>::Intersection_results 00081 Ray_2_Segment_2_pair<K>::intersection_type() const 00082 { 00083 if (_known) 00084 return _result; 00085 // The non const this pointer is used to cast away const. 00086 _known = true; 00087 // if (!do_overlap(_ray->bbox(), _seg->bbox())) 00088 // return NO_INTERSECTION; 00089 const typename K::Line_2 &l1 = _ray->supporting_line(); 00090 const typename K::Line_2 &l2 = _seg->supporting_line(); 00091 Line_2_Line_2_pair<K> linepair(&l1, &l2); 00092 switch ( linepair.intersection_type()) { 00093 case Line_2_Line_2_pair<K>::NO_INTERSECTION: 00094 _result = NO_INTERSECTION; 00095 return _result; 00096 case Line_2_Line_2_pair<K>::POINT: 00097 _intersection_point = linepair.intersection_point(); 00098 _result = (_ray->collinear_has_on(_intersection_point) 00099 && _seg->collinear_has_on(_intersection_point) ) 00100 ? POINT : NO_INTERSECTION; 00101 return _result; 00102 case Line_2_Line_2_pair<K>::LINE: { 00103 typedef typename K::RT RT; 00104 const typename K::Point_2 &start1 = _seg->source(); 00105 const typename K::Point_2 &end1 = _seg->target(); 00106 const typename K::Point_2 &start2 = _ray->source(); 00107 const typename K::Point_2 *minpt, *maxpt; 00108 typename K::Vector_2 diff1 = end1-start1; 00109 if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) { 00110 typedef typename K::FT FT; 00111 if (start1.x() < end1.x()) { 00112 minpt = &start1; 00113 maxpt = &end1; 00114 } else { 00115 minpt = &end1; 00116 maxpt = &start1; 00117 } 00118 if (_ray->direction().to_vector().x() > FT(0)) { 00119 if (maxpt->x() < start2.x()) { 00120 _result = NO_INTERSECTION; 00121 return _result; 00122 } 00123 if (maxpt->x() == start2.x()) { 00124 _intersection_point = *maxpt; 00125 _result = POINT; 00126 return _result; 00127 } 00128 if (minpt->x() < start2.x()) { 00129 _intersection_point = start2; 00130 _other_point = *maxpt; 00131 } else { 00132 _intersection_point = _seg->source(); 00133 _other_point = _seg->target(); 00134 } 00135 _result = SEGMENT; 00136 return _result; 00137 } else { 00138 if (minpt->x() > start2.x()) { 00139 _result = NO_INTERSECTION; 00140 return _result; 00141 } 00142 if (minpt->x() == start2.x()) { 00143 _intersection_point = *minpt; 00144 _result = POINT; 00145 return _result; 00146 } 00147 if (maxpt->x() > start2.x()) { 00148 _intersection_point = start2; 00149 _other_point = *maxpt; 00150 } else { 00151 _intersection_point = _seg->source(); 00152 _other_point = _seg->target(); 00153 } 00154 _result = SEGMENT; 00155 return _result; 00156 } 00157 } else { 00158 typedef typename K::FT FT; 00159 if (start1.y() < end1.y()) { 00160 minpt = &start1; 00161 maxpt = &end1; 00162 } else { 00163 minpt = &end1; 00164 maxpt = &start1; 00165 } 00166 if (_ray->direction().to_vector().y() > FT(0)) { 00167 if (maxpt->y() < start2.y()) { 00168 _result = NO_INTERSECTION; 00169 return _result; 00170 } 00171 if (maxpt->y() == start2.y()) { 00172 _intersection_point = *maxpt; 00173 _result = POINT; 00174 return _result; 00175 } 00176 if (minpt->y() < start2.y()) { 00177 _intersection_point = start2; 00178 _other_point = *maxpt; 00179 } else { 00180 _intersection_point = _seg->source(); 00181 _other_point = _seg->target(); 00182 } 00183 _result = SEGMENT; 00184 return _result; 00185 } else { 00186 if (minpt->y() > start2.y()) { 00187 _result = NO_INTERSECTION; 00188 return _result; 00189 } 00190 if (minpt->y() == start2.y()) { 00191 _intersection_point = *minpt; 00192 _result = POINT; 00193 return _result; 00194 } 00195 if (maxpt->y() > start2.y()) { 00196 _intersection_point = start2; 00197 _other_point = *maxpt; 00198 } else { 00199 _intersection_point = _seg->source(); 00200 _other_point = _seg->target(); 00201 } 00202 _result = SEGMENT; 00203 return _result; 00204 } 00205 } 00206 } 00207 default: 00208 CGAL_kernel_assertion(false); // should not be reached: 00209 return _result; 00210 } 00211 00212 } 00213 00214 template <class K> 00215 typename K::Point_2 00216 Ray_2_Segment_2_pair<K>::intersection_point() const 00217 { 00218 if (!_known) 00219 intersection_type(); 00220 CGAL_kernel_assertion(_result == POINT); 00221 return _intersection_point; 00222 } 00223 00224 template <class K> 00225 typename K::Segment_2 00226 Ray_2_Segment_2_pair<K>::intersection_segment() const 00227 { 00228 typedef typename K::Segment_2 Segment_2; 00229 if (!_known) 00230 intersection_type(); 00231 CGAL_kernel_assertion(_result == SEGMENT); 00232 return Segment_2(_intersection_point, _other_point); 00233 } 00234 00235 00236 00237 template <class K> 00238 Object 00239 intersection(const typename K::Ray_2 &ray, 00240 const typename K::Segment_2&seg, 00241 const K&) 00242 { 00243 typedef Ray_2_Segment_2_pair<K> is_t; 00244 is_t ispair(&ray, &seg); 00245 switch (ispair.intersection_type()) { 00246 case is_t::NO_INTERSECTION: 00247 default: 00248 return Object(); 00249 case is_t::POINT: 00250 return make_object(ispair.intersection_point()); 00251 case is_t::SEGMENT: 00252 return make_object(ispair.intersection_segment()); 00253 } 00254 } 00255 00256 00257 template <class K> 00258 Object 00259 intersection(const typename K::Segment_2 &seg, 00260 const typename K::Ray_2 &ray, 00261 const K& k) 00262 { 00263 return CGALi::intersection(ray, seg, k); 00264 } 00265 00266 } // namespace CGALi 00267 00268 template <class K> 00269 inline bool do_intersect( 00270 const Segment_2<K> &p1, 00271 const Ray_2<K> &p2) 00272 { 00273 typedef typename K::Do_intersect_2 Do_intersect; 00274 return Do_intersect()(p1, p2); 00275 } 00276 00277 template <class K> 00278 inline bool do_intersect( 00279 const Ray_2<K> &p1, 00280 const Segment_2<K> &p2) 00281 { 00282 typedef typename K::Do_intersect_2 Do_intersect; 00283 return Do_intersect()(p2, p1); 00284 } 00285 00286 template <class K> 00287 inline Object 00288 intersection(const Segment_2<K> &seg, const Ray_2<K> &ray) 00289 { 00290 typedef typename K::Intersect_2 Intersect; 00291 return Intersect()(ray, seg); 00292 } 00293 00294 template <class K> 00295 inline Object 00296 intersection(const Ray_2<K> &ray, const Segment_2<K> &seg) 00297 { 00298 typedef typename K::Intersect_2 Intersect; 00299 return Intersect()(ray, seg); 00300 } 00301 00302 CGAL_END_NAMESPACE 00303 00304 #endif