BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Ray_2_Segment_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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines