BWAPI
|
00001 // Copyright (c) 2000 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/Cartesian_kernel/include/CGAL/Cartesian/Sphere_3.h $ 00019 // $Id: Sphere_3.h 50112 2009-06-26 14:15:56Z sloriot $ 00020 // 00021 // 00022 // Author(s) : Herve Bronnimann 00023 00024 #ifndef CGAL_CARTESIAN_SPHERE_3_H 00025 #define CGAL_CARTESIAN_SPHERE_3_H 00026 00027 #include <CGAL/Handle_for.h> 00028 #include <CGAL/Interval_nt.h> 00029 #include <boost/tuple/tuple.hpp> 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 template <class R_> 00034 class SphereC3 00035 { 00036 typedef typename R_::FT FT; 00037 typedef typename R_::Point_3 Point_3; 00038 typedef typename R_::Vector_3 Vector_3; 00039 typedef typename R_::Sphere_3 Sphere_3; 00040 typedef typename R_::Circle_3 Circle_3; 00041 00042 typedef boost::tuple<Point_3, FT, Orientation> Rep; 00043 typedef typename R_::template Handle<Rep>::type Base; 00044 00045 Base base; 00046 00047 public: 00048 typedef R_ R; 00049 00050 SphereC3() {} 00051 00052 SphereC3(const Point_3 ¢er, const FT &squared_radius, 00053 const Orientation &o = COUNTERCLOCKWISE) 00054 { 00055 CGAL_kernel_precondition( (squared_radius >= FT(0)) & 00056 (o != COLLINEAR) ); 00057 00058 base = Rep(center, squared_radius, o); 00059 } 00060 00061 // Sphere passing through and oriented by p,q,r,s 00062 SphereC3(const Point_3 &p, const Point_3 &q, 00063 const Point_3 &r, const Point_3 &s) 00064 { 00065 Orientation orient = make_certain(CGAL::orientation(p, q, r, s)); 00066 Point_3 center = circumcenter(p, q, r, s); 00067 FT squared_radius = squared_distance(p, center); 00068 00069 base = Rep(center, squared_radius, orient); 00070 } 00071 00072 // Sphere with great circle passing through p,q,r, oriented by o 00073 SphereC3(const Point_3 &p, const Point_3 &q, const Point_3 &r, 00074 const Orientation &o = COUNTERCLOCKWISE) 00075 { 00076 CGAL_kernel_precondition(o != COLLINEAR); 00077 00078 Point_3 center = circumcenter(p, q, r); 00079 FT squared_radius = squared_distance(p, center); 00080 00081 base = Rep(center, squared_radius, o); 00082 } 00083 00084 // Sphere with diameter pq and orientation o 00085 SphereC3(const Point_3 &p, const Point_3 &q, 00086 const Orientation &o = COUNTERCLOCKWISE) 00087 { 00088 CGAL_kernel_precondition(o != COLLINEAR); 00089 00090 Point_3 center = midpoint(p, q); 00091 FT squared_radius = squared_distance(p, center); 00092 00093 base = Rep(center, squared_radius, o); 00094 } 00095 00096 explicit SphereC3(const Point_3 ¢er, 00097 const Orientation& o = COUNTERCLOCKWISE) 00098 { 00099 CGAL_kernel_precondition(o != COLLINEAR); 00100 00101 base = Rep(center, FT(0), o); 00102 } 00103 00104 typename R::Boolean operator==(const SphereC3 &) const; 00105 typename R::Boolean operator!=(const SphereC3 &) const; 00106 00107 const Point_3 & center() const 00108 { 00109 return get(base).get<0>(); 00110 } 00111 const FT & squared_radius() const 00112 { 00113 // Returns the square of the radius (instead of the radius itself, 00114 // which would require square roots) 00115 return get(base).get<1>(); 00116 } 00117 Orientation orientation() const 00118 { 00119 return get(base).get<2>(); 00120 } 00121 00122 // A circle is degenerate if its (squared) radius is null or negative 00123 typename R::Boolean is_degenerate() const; 00124 00125 // Returns a circle with opposite orientation 00126 Sphere_3 opposite() const; 00127 00128 typename R_::Oriented_side oriented_side(const Point_3 &p) const; 00130 // Returns R::ON_POSITIVE_SIDE, R::ON_ORIENTED_BOUNDARY or 00131 // R::ON_NEGATIVE_SIDE 00132 typename R::Boolean has_on(const Circle_3 &p) const; 00133 typename R::Boolean has_on(const Point_3 &p) const; 00134 typename R::Boolean has_on_boundary(const Point_3 &p) const; 00135 typename R::Boolean has_on_positive_side(const Point_3 &p) const; 00136 typename R::Boolean has_on_negative_side(const Point_3 &p) const; 00137 00138 typename R_::Bounded_side bounded_side(const Point_3 &p) const; 00140 // Returns R::ON_BOUNDED_SIDE, R::ON_BOUNDARY or R::ON_UNBOUNDED_SIDE 00141 typename R::Boolean has_on_bounded_side(const Point_3 &p) const; 00142 typename R::Boolean has_on_unbounded_side(const Point_3 &p) const; 00143 }; 00144 00145 template < class R > 00146 CGAL_KERNEL_INLINE 00147 typename R::Boolean 00148 SphereC3<R>::operator==(const SphereC3<R> &t) const 00149 { 00150 if (CGAL::identical(base, t.base)) 00151 return true; 00152 return center() == t.center() && 00153 squared_radius() == t.squared_radius() && 00154 orientation() == t.orientation(); 00155 } 00156 00157 template < class R > 00158 inline 00159 typename R::Boolean 00160 SphereC3<R>::operator!=(const SphereC3<R> &t) const 00161 { 00162 return !(*this == t); 00163 } 00164 00165 template < class R > 00166 CGAL_KERNEL_MEDIUM_INLINE 00167 typename R::Oriented_side 00168 SphereC3<R>:: 00169 oriented_side(const typename SphereC3<R>::Point_3 &p) const 00170 { 00171 return enum_cast<Oriented_side>(bounded_side(p)) * orientation(); 00172 } 00173 00174 template < class R > 00175 CGAL_KERNEL_INLINE 00176 typename R::Bounded_side 00177 SphereC3<R>:: 00178 bounded_side(const typename SphereC3<R>::Point_3 &p) const 00179 { 00180 return enum_cast<Bounded_side>(compare(squared_radius(), 00181 squared_distance(center(), p))); 00182 } 00183 00184 template < class R > 00185 inline 00186 typename R::Boolean 00187 SphereC3<R>:: 00188 has_on(const typename SphereC3<R>::Circle_3 &c) const 00189 { 00190 typedef typename SphereC3<R>::Point_3 Point_3; 00191 typedef typename SphereC3<R>::FT FT; 00192 Point_3 proj = c.supporting_plane().projection(center()); 00193 if(!(proj == c.center())) return false; 00194 const FT d2 = squared_distance(center(),c.center()); 00195 return ((squared_radius() - d2) == c.squared_radius()); 00196 } 00197 00198 template < class R > 00199 inline 00200 typename R::Boolean 00201 SphereC3<R>:: 00202 has_on(const typename SphereC3<R>::Point_3 &p) const 00203 { 00204 return has_on_boundary(p); 00205 } 00206 00207 template < class R > 00208 inline 00209 typename R::Boolean 00210 SphereC3<R>:: 00211 has_on_boundary(const typename SphereC3<R>::Point_3 &p) const 00212 { 00213 // FIXME: it's a predicate... 00214 return squared_distance(center(),p) == squared_radius(); 00215 // NB: J'ai aussi trouve ailleurs : 00216 // return oriented_side(p)==ON_ORIENTED_BOUNDARY; 00217 // a voir... 00218 } 00219 00220 template < class R > 00221 CGAL_KERNEL_INLINE 00222 typename R::Boolean 00223 SphereC3<R>:: 00224 has_on_negative_side(const typename SphereC3<R>::Point_3 &p) const 00225 { 00226 if (orientation() == COUNTERCLOCKWISE) 00227 return has_on_unbounded_side(p); 00228 return has_on_bounded_side(p); 00229 // NB: J'ai aussi trouve ailleurs : 00230 // return oriented_side(p)==ON_NEGATIVE_SIDE; 00231 } 00232 00233 template < class R > 00234 CGAL_KERNEL_INLINE 00235 typename R::Boolean 00236 SphereC3<R>:: 00237 has_on_positive_side(const typename SphereC3<R>::Point_3 &p) const 00238 { 00239 if (orientation() == COUNTERCLOCKWISE) 00240 return has_on_bounded_side(p); 00241 return has_on_unbounded_side(p); 00242 // NB: J'ai aussi trouve ailleurs : 00243 // return oriented_side(p)==ON_POSITIVE_SIDE; 00244 } 00245 00246 template < class R > 00247 inline 00248 typename R::Boolean 00249 SphereC3<R>:: 00250 has_on_bounded_side(const typename SphereC3<R>::Point_3 &p) const 00251 { 00252 // FIXME: it's a predicate... 00253 return squared_distance(center(),p) < squared_radius(); 00254 // NB: J'ai aussi trouve ailleurs : 00255 // return bounded_side(p)==ON_BOUNDED_SIDE; 00256 } 00257 00258 template < class R > 00259 inline 00260 typename R::Boolean 00261 SphereC3<R>:: 00262 has_on_unbounded_side(const typename SphereC3<R>::Point_3 &p) const 00263 { 00264 // FIXME: it's a predicate... 00265 return squared_distance(center(),p) > squared_radius(); 00266 // NB: J'ai aussi trouve ailleurs : 00267 // return bounded_side(p)==ON_UNBOUNDED_SIDE; 00268 } 00269 00270 template < class R > 00271 inline 00272 typename R::Boolean 00273 SphereC3<R>:: 00274 is_degenerate() const 00275 { 00276 // FIXME: it's a predicate (?) 00277 return CGAL_NTS is_zero(squared_radius()); 00278 } 00279 00280 template < class R > 00281 inline 00282 typename SphereC3<R>::Sphere_3 00283 SphereC3<R>::opposite() const 00284 { 00285 return SphereC3<R>(center(), squared_radius(), 00286 CGAL::opposite(orientation()) ); 00287 } 00288 00289 CGAL_END_NAMESPACE 00290 00291 #endif // CGAL_CARTESIAN_SPHERE_3_H