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/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