BWAPI
|
00001 // Copyright (c) 1999 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/Kernel_23/include/CGAL/Segment_2.h $ 00019 // $Id: Segment_2.h 42932 2008-04-17 10:13:31Z spion $ 00020 // 00021 // 00022 // Author(s) : Andreas Fabri 00023 00024 #ifndef CGAL_SEGMENT_2_H 00025 #define CGAL_SEGMENT_2_H 00026 00027 #include <boost/static_assert.hpp> 00028 #include <boost/type_traits.hpp> 00029 #include <CGAL/Kernel/Return_base_tag.h> 00030 #include <CGAL/Bbox_2.h> 00031 #include <CGAL/Dimension.h> 00032 00033 CGAL_BEGIN_NAMESPACE 00034 00035 template <class R_> 00036 class Segment_2 : public R_::Kernel_base::Segment_2 00037 { 00038 typedef typename R_::RT RT; 00039 typedef typename R_::FT FT; 00040 typedef typename R_::Point_2 Point_2; 00041 typedef typename R_::Direction_2 Direction_2; 00042 typedef typename R_::Vector_2 Vector_2; 00043 typedef typename R_::Line_2 Line_2; 00044 typedef typename R_::Aff_transformation_2 Aff_transformation_2; 00045 typedef typename R_::Kernel_base::Segment_2 RSegment_2; 00046 00047 typedef Segment_2 Self; 00048 BOOST_STATIC_ASSERT((boost::is_same<Self, typename R_::Segment_2>::value)); 00049 00050 public: 00051 00052 typedef Dimension_tag<2> Ambient_dimension; 00053 typedef Dimension_tag<1> Feature_dimension; 00054 00055 typedef RSegment_2 Rep; 00056 00057 const Rep& rep() const 00058 { 00059 return *this; 00060 } 00061 00062 Rep& rep() 00063 { 00064 return *this; 00065 } 00066 00067 typedef R_ R; 00068 00069 Segment_2() {} 00070 00071 // conversion from implementation class object to interface class object 00072 Segment_2(const RSegment_2& s) 00073 : RSegment_2(s) {} 00074 00075 Segment_2(const Point_2 &sp, const Point_2 &ep) 00076 : RSegment_2(typename R::Construct_segment_2()(Return_base_tag(), sp,ep)) {} 00077 00078 typename Qualified_result_of<typename R::Construct_source_2, Segment_2>::type 00079 source() const 00080 { 00081 return R_().construct_source_2_object()(*this); 00082 } 00083 00084 typename Qualified_result_of<typename R::Construct_target_2, Segment_2>::type 00085 target() const 00086 { 00087 return R_().construct_target_2_object()(*this); 00088 } 00089 00090 typename Qualified_result_of<typename R::Construct_source_2, Segment_2>::type 00091 start() const 00092 { 00093 return source(); 00094 } 00095 00096 typename Qualified_result_of<typename R::Construct_target_2, Segment_2>::type 00097 end() const 00098 { 00099 return target(); 00100 } 00101 00102 00103 typename Qualified_result_of<typename R::Construct_min_vertex_2, Segment_2>::type 00104 min BOOST_PREVENT_MACRO_SUBSTITUTION () const; 00105 00106 typename Qualified_result_of<typename R::Construct_max_vertex_2, Segment_2>::type 00107 max BOOST_PREVENT_MACRO_SUBSTITUTION () const; 00108 00109 typename Qualified_result_of<typename R::Construct_vertex_2, Segment_2, int>::type 00110 vertex(int i) const; 00111 00112 typename Qualified_result_of<typename R::Construct_vertex_2, Segment_2, int>::type 00113 point(int i) const; 00114 00115 typename Qualified_result_of<typename R::Construct_vertex_2, Segment_2, int>::type 00116 operator[](int i) const; 00117 00118 bool is_horizontal() const; 00119 bool is_vertical() const; 00120 bool has_on(const Point_2 &p) const; 00121 bool collinear_has_on(const Point_2 &p) const; 00122 FT squared_length() const; 00123 00124 bool is_degenerate() const; 00125 00126 Bbox_2 bbox() const 00127 { 00128 return R().construct_bbox_2_object()(*this); 00129 } 00130 00131 bool 00132 operator==(const Segment_2 &s) const 00133 { 00134 return R().equal_2_object()(*this, s); 00135 } 00136 00137 bool 00138 operator!=(const Segment_2 &s) const 00139 { 00140 return !(*this == s); 00141 } 00142 00143 00144 Direction_2 00145 direction() const 00146 { 00147 typename R::Construct_vector_2 construct_vector; 00148 return Direction_2( construct_vector( source(), target())); 00149 } 00150 00151 Vector_2 00152 to_vector() const 00153 { 00154 typename R::Construct_vector_2 construct_vector; 00155 return construct_vector( source(), target()); 00156 } 00157 00158 Line_2 00159 supporting_line() const 00160 { 00161 typename R::Construct_line_2 construct_line; 00162 return construct_line(*this); 00163 } 00164 00165 Segment_2 00166 opposite() const 00167 { 00168 return R().construct_opposite_segment_2_object()(*this); 00169 } 00170 00171 Segment_2 00172 transform(const Aff_transformation_2 &t) const 00173 { 00174 return Segment_2(t.transform(source()), t.transform(target())); 00175 } 00176 }; 00177 00178 template < class R_ > 00179 CGAL_KERNEL_INLINE 00180 typename Qualified_result_of<typename R_::Construct_min_vertex_2, Segment_2<R_> >::type 00181 Segment_2<R_>::min BOOST_PREVENT_MACRO_SUBSTITUTION () const 00182 { 00183 typename R_::Less_xy_2 less_xy; 00184 return less_xy(source(),target()) ? source() : target(); 00185 } 00186 00187 template < class R_ > 00188 CGAL_KERNEL_INLINE 00189 typename Qualified_result_of<typename R_::Construct_max_vertex_2, Segment_2<R_> >::type 00190 Segment_2<R_>::max BOOST_PREVENT_MACRO_SUBSTITUTION () const 00191 { 00192 typename R_::Less_xy_2 less_xy; 00193 return less_xy(source(),target()) ? target() : source(); 00194 } 00195 00196 template < class R_ > 00197 CGAL_KERNEL_INLINE 00198 typename Qualified_result_of<typename R_::Construct_vertex_2, Segment_2<R_>, int >::type 00199 Segment_2<R_>::vertex(int i) const 00200 { 00201 return (i%2 == 0) ? source() : target(); 00202 } 00203 00204 template < class R_ > 00205 inline 00206 typename Qualified_result_of<typename R_::Construct_vertex_2, Segment_2<R_>, int >::type 00207 Segment_2<R_>::point(int i) const 00208 { 00209 return vertex(i); 00210 } 00211 00212 template < class R_ > 00213 inline 00214 typename Qualified_result_of<typename R_::Construct_vertex_2, Segment_2<R_>, int >::type 00215 Segment_2<R_>::operator[](int i) const 00216 { 00217 return vertex(i); 00218 } 00219 00220 template < class R_ > 00221 CGAL_KERNEL_INLINE 00222 bool 00223 Segment_2<R_>::is_horizontal() const 00224 { 00225 return R_().equal_y_2_object()(source(), target()); 00226 } 00227 00228 00229 template < class R_ > 00230 CGAL_KERNEL_INLINE 00231 bool 00232 Segment_2<R_>::is_vertical() const 00233 { 00234 return R_().equal_x_2_object()(source(), target()); 00235 } 00236 00237 00238 template < class R_ > 00239 CGAL_KERNEL_INLINE 00240 bool 00241 Segment_2<R_>:: 00242 has_on(const typename R_::Point_2 &p) const 00243 { 00244 return R_().are_ordered_along_line_2_object()(source(), 00245 p, 00246 target()); 00247 } 00248 00249 00250 template < class R_ > 00251 inline 00252 bool 00253 Segment_2<R_>:: 00254 collinear_has_on(const typename R_::Point_2 &p) const 00255 { 00256 return R_().collinear_has_on_2_object() 00257 (*this, p); 00258 } 00259 00260 00261 template < class R_ > 00262 CGAL_KERNEL_INLINE 00263 typename Segment_2<R_>::FT 00264 Segment_2<R_>::squared_length() const 00265 { 00266 return R_().compute_squared_length_2_object()(*this); 00267 } 00268 00269 00270 template < class R_ > 00271 inline 00272 bool 00273 Segment_2<R_>::is_degenerate() const 00274 { 00275 return R().is_degenerate_2_object()(*this); 00276 } 00277 00278 00279 00280 template < class R > 00281 std::ostream & 00282 operator<<(std::ostream &os, const Segment_2<R> &s) 00283 { 00284 switch(os.iword(IO::mode)) { 00285 case IO::ASCII : 00286 return os << s.source() << ' ' << s.target(); 00287 case IO::BINARY : 00288 return os << s.source() << s.target(); 00289 default: 00290 return os << "Segment_2(" << s.source() << ", " << s.target() << ")"; 00291 } 00292 } 00293 00294 template < class R > 00295 std::istream & 00296 operator>>(std::istream &is, Segment_2<R> &s) 00297 { 00298 typename R::Point_2 p, q; 00299 00300 is >> p >> q; 00301 00302 if (is) 00303 s = Segment_2<R>(p, q); 00304 return is; 00305 } 00306 00307 CGAL_END_NAMESPACE 00308 00309 #endif // CGAL_SEGMENT_2_H