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/Circle_2.h $ 00019 // $Id: Circle_2.h 45156 2008-08-26 13:40:26Z spion $ 00020 // 00021 // 00022 // Author(s) : Andreas Fabri 00023 // Sven Schoenherr 00024 00025 #ifndef CGAL_CIRCLE_2_H 00026 #define CGAL_CIRCLE_2_H 00027 00028 #include <boost/static_assert.hpp> 00029 #include <boost/type_traits.hpp> 00030 #include <CGAL/Kernel/Return_base_tag.h> 00031 #include <CGAL/Bbox_2.h> 00032 #include <CGAL/Dimension.h> 00033 00034 CGAL_BEGIN_NAMESPACE 00035 00036 template <class R_> 00037 class Circle_2 : public R_::Kernel_base::Circle_2 00038 { 00039 typedef typename R_::FT FT; 00040 typedef typename R_::Point_2 Point_2; 00041 typedef typename R_::Kernel_base::Circle_2 RCircle_2; 00042 typedef typename R_::Aff_transformation_2 Aff_transformation_2; 00043 00044 typedef Circle_2 Self; 00045 BOOST_STATIC_ASSERT((boost::is_same<Self, typename R_::Circle_2>::value)); 00046 00047 public: 00048 00049 typedef Dimension_tag<2> Ambient_dimension; 00050 typedef Dimension_tag<1> Feature_dimension; 00051 00052 typedef RCircle_2 Rep; 00053 00054 const Rep& rep() const 00055 { 00056 return *this; 00057 } 00058 00059 Rep& rep() 00060 { 00061 return *this; 00062 } 00063 00064 typedef R_ R; 00065 00066 Circle_2() {} 00067 00068 Circle_2(const RCircle_2& t) 00069 : RCircle_2(t) {} 00070 00071 Circle_2(const Point_2 ¢er, const FT &squared_radius, 00072 const Orientation &orientation) 00073 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), center, squared_radius, orientation)) {} 00074 00075 Circle_2(const Point_2 ¢er, const FT &squared_radius) 00076 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), center, squared_radius, COUNTERCLOCKWISE)) {} 00077 00078 Circle_2(const Point_2 &p, const Point_2 &q, const Point_2 &r) 00079 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), p, q, r)) {} 00080 00081 Circle_2(const Point_2 & p, const Point_2 & q, 00082 const Orientation &orientation) 00083 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), p, q, orientation)) {} 00084 00085 Circle_2(const Point_2 & p, const Point_2 & q) 00086 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), p, q, COUNTERCLOCKWISE)) {} 00087 00088 Circle_2(const Point_2 & p, const Point_2 & q, const FT &bulge) 00089 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), p, q, bulge)) {} 00090 00091 Circle_2(const Point_2 & center, const Orientation& orientation) 00092 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), center, FT(0), orientation)) {} 00093 00094 Circle_2(const Point_2 & center) 00095 : RCircle_2(typename R::Construct_circle_2()(Return_base_tag(), center, FT(0), COUNTERCLOCKWISE)) {} 00096 00097 typename Qualified_result_of<typename R::Construct_center_2,Circle_2>::type 00098 center() const 00099 { 00100 return R().construct_center_2_object()(*this); 00101 } 00102 00103 typename Qualified_result_of<typename R::Compute_squared_radius_2,Circle_2>::type 00104 squared_radius() const 00105 { 00106 return R().compute_squared_radius_2_object()(*this); 00107 } 00108 00109 Orientation orientation() const 00110 { 00111 // This make_certain(), the uncertain orientation of circles, the orientation 00112 // of circles, are all yucky. 00113 return make_certain(R().orientation_2_object()(*this)); 00114 } 00115 00116 00117 typename R::Bounded_side 00118 bounded_side(const Point_2 &p) const 00119 { 00120 return R().bounded_side_2_object()(*this, p); 00121 } 00122 00123 typename R::Oriented_side 00124 oriented_side(const Point_2 &p) const 00125 { 00126 return R().oriented_side_2_object()(*this, p); 00127 } 00128 00129 typename R::Boolean 00130 has_on_boundary(const Point_2 &p) const 00131 { 00132 return bounded_side(p) == ON_BOUNDARY; 00133 } 00134 00135 typename R::Boolean 00136 has_on_bounded_side(const Point_2 &p) const 00137 { 00138 return bounded_side(p) == ON_BOUNDED_SIDE; 00139 } 00140 00141 typename R::Boolean 00142 has_on_unbounded_side(const Point_2 &p) const 00143 { 00144 return bounded_side(p) == ON_UNBOUNDED_SIDE; 00145 } 00146 00147 typename R::Boolean 00148 has_on_negative_side(const Point_2 &p) const 00149 { 00150 if (orientation() == COUNTERCLOCKWISE) 00151 return has_on_unbounded_side(p); 00152 return has_on_bounded_side(p); 00153 } 00154 00155 typename R::Boolean 00156 has_on_positive_side(const Point_2 &p) const 00157 { 00158 if (orientation() == COUNTERCLOCKWISE) 00159 return has_on_bounded_side(p); 00160 return has_on_unbounded_side(p); 00161 } 00162 00163 typename R::Boolean 00164 is_degenerate() const 00165 { 00166 return CGAL_NTS is_zero(squared_radius()); 00167 } 00168 00169 Circle_2 00170 opposite() const 00171 { 00172 //return R().construct_opposite_circle_2_object()(*this); 00173 return Circle_2(center(), 00174 squared_radius(), 00175 CGAL::opposite(orientation()) ); 00176 } 00177 00178 Bbox_2 00179 bbox() const 00180 { 00181 return R().construct_bbox_2_object()(*this); 00182 } 00183 00184 typename R::Boolean 00185 operator==(const Circle_2 &c) const 00186 { 00187 return R().equal_2_object()(*this, c); 00188 } 00189 00190 typename R::Boolean 00191 operator!=(const Circle_2 &c) const 00192 { 00193 return !(*this == c); 00194 } 00195 00196 Circle_2 transform(const Aff_transformation_2 &t) const 00197 { 00198 return t.transform(*this); 00199 } 00200 00201 Circle_2 orthogonal_transform(const Aff_transformation_2 &t) const; 00202 00203 00204 }; 00205 00206 template <class R_> 00207 Circle_2<R_> 00208 Circle_2<R_>:: 00209 orthogonal_transform(const typename R_::Aff_transformation_2& t) const 00210 { 00211 typedef typename R_::RT RT; 00212 typedef typename R_::FT FT; 00213 typedef typename R_::Vector_2 Vector_2; 00214 00215 Vector_2 vec(RT(1), RT(0) ); // unit vector // AF: was FT 00216 vec = vec.transform(t); // transformed 00217 FT sq_scale = vec.squared_length(); // squared scaling factor 00218 00219 return Circle_2(t.transform(center()), 00220 sq_scale * squared_radius(), 00221 t.is_even() ? orientation() 00222 : CGAL::opposite(orientation())); 00223 } 00224 00225 00226 template <class R > 00227 std::ostream& 00228 insert(std::ostream& os, const Circle_2<R>& c) 00229 { 00230 switch(os.iword(IO::mode)) { 00231 case IO::ASCII : 00232 os << c.center() << ' ' << c.squared_radius() << ' ' 00233 << static_cast<int>(c.orientation()); 00234 break; 00235 case IO::BINARY : 00236 os << c.center(); 00237 write(os, c.squared_radius()); 00238 write(os, static_cast<int>(c.orientation())); 00239 break; 00240 default: 00241 os << "Circle_2(" << c.center() << ", " << c.squared_radius() ; 00242 switch (c.orientation()) { 00243 case CLOCKWISE: 00244 os << ", clockwise)"; 00245 break; 00246 case COUNTERCLOCKWISE: 00247 os << ", counterclockwise)"; 00248 break; 00249 default: 00250 os << ", collinear)"; 00251 break; 00252 } 00253 break; 00254 } 00255 return os; 00256 } 00257 00258 template < class R > 00259 std::ostream & 00260 operator<<(std::ostream &os, const Circle_2<R> &c) 00261 { 00262 return insert(os, c); 00263 } 00264 00265 00266 template <class R > 00267 std::istream& 00268 extract(std::istream& is, Circle_2<R>& c) 00269 { 00270 typename R::Point_2 center; 00271 typename R::FT squared_radius; 00272 int o; 00273 switch(is.iword(IO::mode)) { 00274 case IO::ASCII : 00275 is >> center >> squared_radius >> o; 00276 break; 00277 case IO::BINARY : 00278 is >> center; 00279 read(is, squared_radius); 00280 is >> o; 00281 break; 00282 default: 00283 std::cerr << "" << std::endl; 00284 std::cerr << "Stream must be in ascii or binary mode" << std::endl; 00285 break; 00286 } 00287 if (is) 00288 c = Circle_2<R>(center, squared_radius, static_cast<Orientation>(o)); 00289 return is; 00290 } 00291 00292 template < class R > 00293 std::istream & 00294 operator>>(std::istream &is, Circle_2<R> &c) 00295 { 00296 return extract(is,c); 00297 } 00298 00299 CGAL_END_NAMESPACE 00300 00301 #endif // CGAL_CIRCLE_2_H