Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sphere.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2005-11-27
7 
8  Copyright (C) 2005,2006 EPFL
9 
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public
12  License as published by the Free Software Foundation; either
13  version 3.0 of the License, or (at your option) any later version.
14 
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public
21  License along with this library; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
29 #ifndef __Sphere_H
30 #define __Sphere_H 1
31 
33 
34 namespace Feel
35 {
74 class Sphere : public Surface
75 {
76  typedef Surface super;
77 
78 public:
79 
80 
84 
85 
87 
91 
92  Sphere()
93  :
94  super(),
95  M_radius( -1 )
96  {}
97 
98  Sphere( Sphere const & s )
99  :
100  super(),
101  M_center( s.M_center ),
102  M_radius( s.M_radius )
103  {
104  }
105 
106  Sphere ( const Point& c,
107  const double r )
108  :
109  super(),
110  M_center( c ),
111  M_radius( r )
112  {
113  assert ( r > 0. );
114 
115  }
116 
117 
118 
119  ~Sphere()
120  {}
121 
123 
127 
128 
130 
134 
138  double radius() const
139  {
140  return M_radius;
141  }
142 
143 
147  const Point& center() const
148  {
149  return M_center;
150  }
151 
152 
153 
154 
156 
160 
164  void setCenter( Point const& p )
165  {
166  M_center = p;
167  }
168 
172  void setRadius( double r )
173  {
174  M_radius = r ;
175  }
176 
177 
179 
183 
187  void createFromCenterRadius ( const Point& c, const double r )
188  {
189  FEELPP_ASSERT( r > 0 )( r ).error( "radius negative" );
190  this->setCenter( c );
191  this->setRadius( r );
192 
193  }
194 
199  bool intersects ( const Sphere& other_sphere ) const
200  {
201  FEELPP_ASSERT( M_radius > 0 )( M_radius ).error( "radius negative" );
202  FEELPP_ASSERT( other_sphere.radius() > 0 )( other_sphere.radius() ).error( "radius negative" );
203 
204  if ( Feel::distance( this->center(), other_sphere.center() ) < ( this->radius() + other_sphere.radius() ) )
205  return true;
206 
207  return false;
208  }
209 
210 
215  bool aboveSurface ( const Point& p ) const
216  {
217  FEELPP_ASSERT( M_radius > 0 )( M_radius ).error( "radius negative" );
218 
219  if ( Feel::distance( p, this->center() ) > this->radius() )
220  return true;
221 
222  return false;
223  }
224 
225 
230  bool belowSurface ( const Point& p ) const
231  {
232  return ( !this->aboveSurface ( p ) );
233  }
234 
235 
242  bool onSurface ( const Point& p ) const
243  {
244  FEELPP_ASSERT( M_radius > 0 )( M_radius ).error( "radius negative" );
245 
246 
247  if ( std::abs( Feel::distance( p, this->center() ) - this->radius() ) < 1.e-10 )
248  return true;
249 
250  return false;
251  }
252 
253 
257  Point closestPoint ( const Point& p ) const
258  {
259  FEELPP_ASSERT( M_radius > 0 )( M_radius ).error( "radius negative" );
260 
261  // get the normal from the surface in the direction
262  // of p
263  Point normal = this->unitNormal ( p );
264 
265  // The closest point on the sphere is in the direction
266  // of the normal a distance r from the center.
267  const Point cp = this->center().node() + normal.node()*this->radius();
268 
269  return cp;
270  }
271 
272 
277  Point unitNormal ( const Point& p ) const
278  {
279  FEELPP_ASSERT( M_radius > 0 )( M_radius ).error( "radius negative" );
280 
281  //assert ( !(p == this->center()) );
282 
283  // Create a vector from the center to the point
284  Point n = p.node() - this->center().node();
285  Point unit_n( n.node()/ ublas::norm_2( n.node() ) );
286 
287  return unit_n;
288  }
289 
290 
291 
296  Point surfaceCoords ( const Point& cart ) const
297  {
298  // constant translation in the origin
299  const Point c ( cart.node() - this->center().node() );
300 
301  // phi: special care, so that it gives 0..2pi results
302  const double phi = std::atan2( c( 1 ), c( 0 ) );
303 
304  return Point( /* radius */ ublas::norm_2( c.node() ),
305  /* theta */ std::atan2( std::sqrt( c( 0 )*c( 0 ) + c( 1 )*c( 1 ) ), c( 2 ) ),
306  /* phi */ ( ( phi < 0 ) ? 2.*M_PI+phi : phi ) );
307  }
308 
309 
314  Point worldCoords ( const Point& sph ) const
315  {
316  const double r = sph( 0 );
317  const double theta = sph( 1 );
318  const double phi = sph( 2 );
319 
320  // constant translation out of the origin
321  return Point ( /* x */ r*std::sin( theta )*std::cos( phi ) + this->center()( 0 ),
322  /* y */ r*std::sin( theta )*std::sin( phi ) + this->center()( 1 ),
323  /* z */ r*std::cos( theta ) + this->center()( 2 ) );
324  }
325 
326 
327 
328 
330 
331 
332 
333 
334 private:
335 
336 
340  Point M_center;
341 
345  Real M_radius;
346 };
347 } // Feel
348 #endif /* __Sphere_H */

Generated on Sun Oct 20 2013 08:25:05 for Feel++ by doxygen 1.8.4