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