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