BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sphere_3.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/Sphere_3.h $
00019 // $Id: Sphere_3.h 50492 2009-07-09 08:20:52Z sloriot $
00020 //
00021 //
00022 // Author(s)     : Stefan Schirra
00023 
00024 #ifndef CGAL_SPHERE_3_H
00025 #define CGAL_SPHERE_3_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_3.h>
00031 #include <CGAL/representation_tags.h>
00032 #include <CGAL/Dimension.h>
00033 
00034 CGAL_BEGIN_NAMESPACE
00035 
00036 template <class R_>
00037 class Sphere_3 : public R_::Kernel_base::Sphere_3
00038 {
00039   typedef typename R_::FT                    FT;
00040   typedef typename R_::Point_3               Point_3;
00041   typedef typename R_::Circle_3              Circle_3;
00042   typedef typename R_::Aff_transformation_3  Aff_transformation_3;
00043 
00044   typedef Sphere_3                           Self;
00045   BOOST_STATIC_ASSERT((boost::is_same<Self, typename R_::Sphere_3>::value));
00046 
00047 public:
00048 
00049   typedef Dimension_tag<3>  Ambient_dimension;
00050   typedef Dimension_tag<2>  Feature_dimension;
00051 
00052   typedef typename R_::Kernel_base::Sphere_3  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   Sphere_3() {}
00067 
00068   Sphere_3(const Rep& s)
00069    : Rep(s) {}
00070 
00071   Sphere_3(const Point_3& p, const FT& sq_rad,
00072            const Orientation& o = COUNTERCLOCKWISE)
00073    : Rep(typename R::Construct_sphere_3()(Return_base_tag(), p, sq_rad, o)) {}
00074 
00075   Sphere_3(const Point_3& p, const Point_3& q,
00076            const Point_3& r, const Point_3& u)
00077    : Rep(typename R::Construct_sphere_3()(Return_base_tag(), p, q, r, u)) {}
00078 
00079   Sphere_3(const Point_3& p, const Point_3& q, const Point_3& r,
00080            const Orientation& o = COUNTERCLOCKWISE)
00081    : Rep(typename R::Construct_sphere_3()(Return_base_tag(), p, q, r, o)) {}
00082 
00083   Sphere_3(const Point_3& p, const Point_3&  q,
00084            const Orientation& o = COUNTERCLOCKWISE)
00085    : Rep(typename R::Construct_sphere_3()(Return_base_tag(), p, q, o)) {}
00086 
00087   explicit Sphere_3(const Point_3& p, const Orientation& o = COUNTERCLOCKWISE)
00088    : Rep(typename R::Construct_sphere_3()(Return_base_tag(), p, o)) {}
00089 
00090   explicit Sphere_3(const Circle_3& c)
00091    : Rep(typename R::Construct_sphere_3()(c)) {}
00092 
00093   Sphere_3 orthogonal_transform(const Aff_transformation_3 &t) const;
00094 
00095   // FIXME : why doesn't Qrt work here ?  We loose optimization !
00096   //typename Qualified_result_of<typename R::Construct_center_3, Sphere_3>::type
00097   Point_3
00098   center() const
00099   {
00100     return R().construct_center_3_object()(*this);
00101   }
00102 
00103   FT
00104   squared_radius() const
00105   {
00106     return R().compute_squared_radius_3_object()(*this);
00107   }
00108 
00109   // Returns a circle with opposite orientation
00110   Sphere_3 opposite() const
00111   {
00112     return R().construct_opposite_sphere_3_object()(*this);
00113   }
00114 
00115   typename R::Orientation orientation() const
00116   {
00117     return R().orientation_3_object()(*this);
00118   }
00119 
00120   typename R::Bounded_side
00121   bounded_side(const Point_3 &p) const
00122   {
00123     return R().bounded_side_3_object()(*this, p);
00124   }
00125 
00126   typename R::Oriented_side
00127   oriented_side(const Point_3 &p) const
00128   {
00129     return R().oriented_side_3_object()(*this, p);
00130   }
00131 
00132   typename R::Boolean
00133   has_on(const Point_3 &p) const
00134   {
00135     return R().has_on_3_object()(*this, p);
00136   }  
00137 
00138   typename R::Boolean
00139   has_on(const Circle_3 &c) const
00140   {
00141     return R().has_on_3_object()(*this, c);
00142   }
00143   
00144   typename R::Boolean
00145   has_on_boundary(const Point_3 &p) const
00146   {
00147     return R().has_on_boundary_3_object()(*this, p);
00148     //return bounded_side(p) == ON_BOUNDARY;
00149   }
00150 
00151   typename R::Boolean
00152   has_on_bounded_side(const Point_3 &p) const
00153   {
00154     return bounded_side(p) == ON_BOUNDED_SIDE;
00155   }
00156 
00157   typename R::Boolean
00158   has_on_unbounded_side(const Point_3 &p) const
00159   {
00160     return bounded_side(p) == ON_UNBOUNDED_SIDE;
00161   }
00162 
00163   typename R::Boolean
00164   has_on_negative_side(const Point_3 &p) const
00165   {
00166     if (orientation() == COUNTERCLOCKWISE)
00167       return has_on_unbounded_side(p);
00168     return has_on_bounded_side(p);
00169   }
00170 
00171   typename R::Boolean
00172   has_on_positive_side(const Point_3 &p) const
00173   {
00174     if (orientation() == COUNTERCLOCKWISE)
00175       return has_on_bounded_side(p);
00176     return has_on_unbounded_side(p);
00177   }
00178 
00179   typename R::Boolean
00180   is_degenerate() const
00181   {
00182     return R().is_degenerate_3_object()(*this);
00183     //return CGAL_NTS is_zero(squared_radius());
00184   }
00185 
00186   Bbox_3
00187   bbox() const
00188   {
00189     return R().construct_bbox_3_object()(*this);
00190   }
00191 
00192 };
00193 
00194 template <class R_>
00195 Sphere_3<R_>
00196 Sphere_3<R_>::
00197 orthogonal_transform(const typename R_::Aff_transformation_3& t) const
00198 {
00199     typedef typename  R_::RT  RT;
00200     typedef typename  R_::FT  FT;
00201     typedef typename  R_::Vector_3  Vector_3;
00202 
00203     // FIXME: precond: t.is_orthogonal() (*UNDEFINED*)
00204     Vector_3 vec(RT(1), RT(0), RT(0));        // unit vector
00205     vec = vec.transform(t);                   // transformed
00206     FT sq_scale = vec.squared_length();       // squared scaling factor
00207 
00208     return Sphere_3(t.transform(this->center()),
00209                     sq_scale * this->squared_radius(),
00210                     t.is_even() ? this->orientation()
00211                                 : CGAL::opposite(this->orientation()));
00212 }
00213 
00214 
00215 template <class R >
00216 std::ostream&
00217 insert(std::ostream& os, const Sphere_3<R>& c,const Cartesian_tag&)
00218 {
00219     switch(os.iword(IO::mode)) {
00220     case IO::ASCII :
00221         os << c.center() << ' ' << c.squared_radius() << ' '
00222            << static_cast<int>(c.orientation());
00223         break;
00224     case IO::BINARY :
00225         os << c.center();
00226         write(os, c.squared_radius());
00227         write(os, static_cast<int>(c.orientation()));
00228         break;
00229     default:
00230         os << "SphereC3(" << c.center() <<  ", " << c.squared_radius();
00231         switch (c.orientation()) {
00232         case CLOCKWISE:
00233             os << ", clockwise)";
00234             break;
00235         case COUNTERCLOCKWISE:
00236             os << ", counterclockwise)";
00237             break;
00238         default:
00239             os << ", collinear)";
00240             break;
00241         }
00242         break;
00243     }
00244     return os;
00245 }
00246 
00247 template <class R >
00248 std::ostream&
00249 insert(std::ostream& os, const Sphere_3<R>& c, const Homogeneous_tag&)
00250 {
00251     switch(os.iword(IO::mode)) {
00252     case IO::ASCII :
00253         os << c.center() << ' ' << c.squared_radius() << ' '
00254            << static_cast<int>(c.orientation());
00255         break;
00256     case IO::BINARY :
00257         os << c.center();
00258         write(os, c.squared_radius());
00259         write(os, static_cast<int>(c.orientation()));
00260         break;
00261     default:
00262         os << "SphereH3(" << c.center() <<  ", " << c.squared_radius();
00263         switch (c.orientation()) {
00264         case CLOCKWISE:
00265             os << ", clockwise)";
00266             break;
00267         case COUNTERCLOCKWISE:
00268             os << ", counterclockwise)";
00269             break;
00270         default:
00271             os << ", collinear)";
00272             break;
00273         }
00274         break;
00275     }
00276     return os;
00277 }
00278 
00279 template < class R >
00280 std::ostream&
00281 operator<<(std::ostream& os, const Sphere_3<R>& c)
00282 {
00283   return insert(os, c, typename R::Kernel_tag() );
00284 }
00285 
00286 
00287 template <class R >
00288 std::istream&
00289 extract(std::istream& is, Sphere_3<R>& c, const Cartesian_tag&)
00290 {
00291     typename R::Point_3 center;
00292     typename R::FT squared_radius;
00293     int o=0;
00294     switch(is.iword(IO::mode)) {
00295     case IO::ASCII :
00296         is >> center >> squared_radius >> o;
00297         break;
00298     case IO::BINARY :
00299         is >> center;
00300         read(is, squared_radius);
00301         is >> o;
00302         break;
00303     default:
00304         std::cerr << "" << std::endl;
00305         std::cerr << "Stream must be in ascii or binary mode" << std::endl;
00306         break;
00307     }
00308     if (is)
00309         c = Sphere_3<R>(center, squared_radius, static_cast<Orientation>(o));
00310     return is;
00311 }
00312 
00313 
00314 template <class R >
00315 std::istream&
00316 extract(std::istream& is, Sphere_3<R>& c, const Homogeneous_tag&)
00317 {
00318     typename R::Point_3 center;
00319     typename R::FT squared_radius;
00320     int o;
00321     switch(is.iword(IO::mode)) {
00322     case IO::ASCII :
00323         is >> center >> squared_radius >> o;
00324         break;
00325     case IO::BINARY :
00326         is >> center;
00327         read(is, squared_radius);
00328         is >> o;
00329         break;
00330     default:
00331         std::cerr << "" << std::endl;
00332         std::cerr << "Stream must be in ascii or binary mode" << std::endl;
00333         break;
00334     }
00335     if (is)
00336         c = Sphere_3<R>(center, squared_radius, static_cast<Orientation>(o));
00337     return is;
00338 }
00339 
00340 template < class R >
00341 std::istream&
00342 operator>>(std::istream& is, Sphere_3<R>& c)
00343 {
00344   return extract(is, c, typename R::Kernel_tag() );
00345 }
00346 
00347 CGAL_END_NAMESPACE
00348 
00349 #endif // CGAL_SPHERE_3_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines