BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Circle_2.h
Go to the documentation of this file.
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 &center, 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 &center, 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines