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