BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Ray_2_Ray_2_intersection.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines