contrib/brl/bbas/bvgl/bvgl_volume_of_intersection.txx
Go to the documentation of this file.
00001 // This is brl/bbas/bvgl/bvgl_volume_of_intersection.txx
00002 #ifndef bvgl_volume_of_intersection_txx_
00003 #define bvgl_volume_of_intersection_txx_
00004 //:
00005 // \file
00006 // \author Andrew Miller
00007 
00008 #include "bvgl_volume_of_intersection.h"
00009 
00010 #include <vcl_limits.h>
00011 #include <vcl_cassert.h>
00012 #include <vcl_cmath.h>
00013 #include <vcl_algorithm.h>
00014 #include <vnl/vnl_math.h>
00015 #include <vgl/vgl_sphere_3d.h>
00016 #include <vcl_vector.h>
00017 
00018 //tolerance constants/functions
00019 static double bvgl_eps = 1.0e-8; // tolerance for intersections
00020 inline bool bvgl_near_zero(double x) { return x < bvgl_eps && x > -bvgl_eps; }
00021 inline bool bvgl_near_eq(double x, double y) { return bvgl_near_zero(x-y); }
00022 
00023 //: calculate the volume of intersection between these two spheres
00024 template <typename T>
00025 T bvgl_volume_of_intersection(vgl_sphere_3d<T> const& A, vgl_sphere_3d<T> const& B)
00026 {
00027   //distance between the two spheres
00028   T d = (A.centre() - B.centre()).length();
00029   T r0 = A.radius();
00030   T r1 = B.radius();
00031 
00032   //cases
00033   //0. if one sphere is completely inside the other one
00034   T difR = vcl_fabs(r0 - r1);
00035   if ( d <= difR )
00036   {
00037     //return the volume of the smaller sphere
00038     T minR = vcl_min(r0, r1);
00039     return (4.0/3.0) * vnl_math::pi * minR * minR * minR;
00040   }
00041 
00042   //2. The two spheres intersect...
00043   T sumR = r0 + r1;
00044   if (d > difR && d < sumR)
00045   {
00046     //calculate distance to the plane of intersection from the center of circle A
00047     T xInt = ( r0*r0 - r1*r1 + d*d ) / (2.0*d) ;
00048 
00049     //calculate height of sperhical caps
00050     T h0 = r0 - xInt;
00051     T h1 = r1 + xInt - d;
00052 
00053     // volume is sum of tops
00054     return (vnl_math::pi/3.0)*( h0*h0 * (3*r0-h0) + h1*h1 * (3*r1-h1) );
00055   }
00056 
00057   //otherwise the two spheres do not intersect
00058   return (T) 0.0;
00059 }
00060 
00061 
00062 //---------------------------------------------------------------------------
00063 //Template instantiation
00064 #undef BVGL_VOLUME_OF_INTERSECTION_INSTANTIATE
00065 #define BVGL_VOLUME_OF_INTERSECTION_INSTANTIATE(T) \
00066 template T bvgl_volume_of_intersection(vgl_sphere_3d<T > const& A, vgl_sphere_3d<T > const& B)
00067 
00068 #endif // bvgl_volume_of_intersection_txx_