BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Ray_2_Iso_rectangle_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_Iso_rectangle_2_intersection.h $
00019 // $Id: Ray_2_Iso_rectangle_2_intersection.h 45356 2008-09-07 15:09:56Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman
00023 
00024 
00025 #ifndef CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H
00026 #define CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H
00027 
00028 #include <CGAL/Iso_rectangle_2.h>
00029 #include <CGAL/Ray_2.h>
00030 #include <CGAL/Segment_2.h>
00031 #include <CGAL/Point_2.h>
00032 #include <CGAL/kernel_assertions.h>
00033 #include <CGAL/number_utils.h>
00034 #include <CGAL/Object.h>
00035 
00036 
00037 CGAL_BEGIN_NAMESPACE
00038 
00039 namespace CGALi {
00040 
00041 template <class K>
00042 class Ray_2_Iso_rectangle_2_pair {
00043 public:
00044     enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT};
00045     Ray_2_Iso_rectangle_2_pair(typename K::Ray_2 const *ray,
00046                           typename K::Iso_rectangle_2 const *iso)
00047       : _known(false), _ref_point(ray->source()), _dir(ray->direction().to_vector()),
00048         _isomin((iso->min)()), _isomax((iso->max)()), _min((typename K::FT)(0)) {}
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 protected:
00055     mutable bool                       _known;
00056     mutable Intersection_results       _result;
00057     mutable typename K::Point_2            _ref_point;
00058     mutable typename K::Vector_2           _dir;
00059     mutable typename K::Point_2            _isomin;
00060     mutable typename K::Point_2            _isomax;
00061     mutable typename K::FT                     _min, _max;
00062 };
00063 
00064 template <class K>
00065 inline bool do_intersect(const typename K::Ray_2 &p1,
00066                          const typename K::Iso_rectangle_2 &p2,
00067                          const K&)
00068 {
00069     typedef Ray_2_Iso_rectangle_2_pair<K> pair_t;
00070     pair_t pair(&p1, &p2);
00071     return pair.intersection_type() != pair_t::NO_INTERSECTION;
00072 }
00073 
00074 template <class K>
00075 inline bool do_intersect(const typename K::Iso_rectangle_2 &p2,
00076                          const typename K::Ray_2 &p1,
00077                          const K& k)
00078 {
00079   return do_intersect(p1, p2, k);
00080 }
00081 
00082 template <class K>
00083 Object
00084 intersection(const typename K::Ray_2 &ray,
00085              const typename K::Iso_rectangle_2 &iso,
00086              const K& )
00087 {
00088     typedef Ray_2_Iso_rectangle_2_pair<K> is_t;
00089     is_t ispair(&ray, &iso);
00090     switch (ispair.intersection_type()) {
00091     case is_t::NO_INTERSECTION:
00092     default:
00093         return Object();
00094     case is_t::POINT:
00095         return make_object(ispair.intersection_point());
00096     case is_t::SEGMENT:
00097         return make_object(ispair.intersection_segment());
00098     }
00099 }
00100 
00101 template <class K>
00102 Object
00103 intersection(const typename K::Iso_rectangle_2 &iso,
00104              const typename K::Ray_2 &ray,
00105              const K& k)
00106 {
00107   return intersection(ray, iso, k);
00108 }
00109 
00110 template <class K>
00111 typename Ray_2_Iso_rectangle_2_pair<K>::Intersection_results
00112 Ray_2_Iso_rectangle_2_pair<K>::intersection_type() const
00113 {
00114     typedef typename K::RT RT;
00115     typedef typename K::FT FT;
00116     if (_known)
00117         return _result;
00118     _known = true;
00119     bool to_infinity = true;
00120 
00121     typename K::Construct_cartesian_const_iterator_2 construct_cccit;
00122     typename K::Cartesian_const_iterator_2 ref_point_it = construct_cccit(_ref_point);
00123     typename K::Cartesian_const_iterator_2 end = construct_cccit(_ref_point, 0);
00124     typename K::Cartesian_const_iterator_2 isomin_it = construct_cccit(_isomin);
00125     typename K::Cartesian_const_iterator_2 isomax_it = construct_cccit(_isomax);
00126 
00127     for (unsigned int i=0; ref_point_it != end; ++i, ++ref_point_it, ++isomin_it, ++isomax_it) {
00128         if (_dir.homogeneous(i) == RT(0)) {
00129             if ((*ref_point_it) < (*isomin_it)) {
00130                 _result = NO_INTERSECTION;
00131                 return _result;
00132             }
00133             if ((*ref_point_it) > (*isomax_it)) {
00134                 _result = NO_INTERSECTION;
00135                 return _result;
00136             }
00137         } else {
00138             FT newmin, newmax;
00139             if (_dir.homogeneous(i) > RT(0)) {
00140                 newmin = (*isomin_it - *ref_point_it) /
00141                     _dir.cartesian(i);
00142                 newmax = (*isomax_it - *ref_point_it) /
00143                     _dir.cartesian(i);
00144             } else {
00145                 newmin = (*isomax_it - *ref_point_it) /
00146                     _dir.cartesian(i);
00147                 newmax = (*isomin_it - *ref_point_it) /
00148                     _dir.cartesian(i);
00149             }
00150             if (newmin > _min)
00151                 _min = newmin;
00152             if (to_infinity) {
00153                 _max = newmax;
00154             } else {
00155                 if (newmax < _max)
00156                     _max = newmax;
00157             }
00158             if (_max < _min) {
00159                 _result = NO_INTERSECTION;
00160                 return _result;
00161             }
00162             to_infinity = false;
00163         }
00164     }
00165     CGAL_kernel_assertion(!to_infinity);
00166     if (_max == _min) {
00167         _result = POINT;
00168         return _result;
00169     }
00170     _result = SEGMENT;
00171     return _result;
00172 }
00173 
00174 
00175 template <class K>
00176 typename K::Segment_2
00177 Ray_2_Iso_rectangle_2_pair<K>::intersection_segment() const
00178 {
00179     typedef typename K::Segment_2 Segment_2; 
00180     typename K::Construct_translated_point_2 translated_point;
00181     typename K::Construct_scaled_vector_2 construct_scaled_vector;
00182     if (!_known)
00183         intersection_type();
00184     CGAL_kernel_assertion(_result == SEGMENT);
00185     typename K::Point_2 p1(translated_point(_ref_point, construct_scaled_vector(_dir,_min)));
00186     typename K::Point_2 p2(translated_point(_ref_point, construct_scaled_vector(_dir,_max)));
00187     return Segment_2(p1, p2);
00188 }
00189 
00190 template <class K>
00191 typename K::Point_2
00192 Ray_2_Iso_rectangle_2_pair<K>::intersection_point() const
00193 {
00194     typedef typename K::Point_2 Point_2;
00195     typename K::Construct_translated_point_2 translated_point;
00196     typename K::Construct_scaled_vector_2 construct_scaled_vector;
00197     if (!_known)
00198         intersection_type();
00199     CGAL_kernel_assertion(_result == POINT);
00200     return Point_2(translated_point(_ref_point, construct_scaled_vector(_dir, _min)));
00201 }
00202 
00203 } // namespace CGALi
00204 
00205 
00206 template <class K>
00207 inline bool do_intersect(const Iso_rectangle_2<K> &p1,
00208                          const Ray_2<K> &p2)
00209 {
00210   typedef typename K::Do_intersect_2 Do_intersect;
00211   return Do_intersect()(p1, p2);
00212 }
00213 
00214 template <class K>
00215 inline bool do_intersect(const Ray_2<K> &p2,
00216                          const Iso_rectangle_2<K> &p1)
00217 {
00218   typedef typename K::Do_intersect_2 Do_intersect;
00219   return Do_intersect()(p1, p2);
00220 }
00221 
00222 
00223 template <class K>
00224 inline Object
00225 intersection(const Iso_rectangle_2<K>&iso, const Ray_2<K>&ray)
00226 {
00227   typedef typename K::Intersect_2 Intersect;
00228   return Intersect()(ray, iso);
00229 }
00230 
00231 template <class K>
00232 inline Object
00233 intersection(const Ray_2<K>&ray, const Iso_rectangle_2<K>&iso)
00234 {
00235   typedef typename K::Intersect_2 Intersect;
00236   return Intersect()(ray, iso);
00237 }
00238 
00239 CGAL_END_NAMESPACE
00240 
00241 #endif // CGAL_RAY_2_iSO_RECTANGLE_2_INTERSECTION_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines