Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

rsdl_dist.cxx

Go to the documentation of this file.
00001 #include "rsdl_dist.h"
00002 
00003 #include <vcl_cassert.h>
00004 #include <vcl_cmath.h>
00005 #include <vnl/vnl_math.h>
00006 
00007 double
00008 rsdl_dist_sq( const rsdl_point& p, const rsdl_point& q )
00009 {
00010   unsigned int Nc = p.num_cartesian();
00011   unsigned int Na = p.num_angular();
00012   assert( Nc == q.num_cartesian() && Na == q.num_angular() );
00013 
00014   double sum_sq = 0;
00015 
00016   for ( unsigned int i=0; i<Nc; ++i ) {
00017     sum_sq += vnl_math_sqr( p.cartesian(i) - q.cartesian(i) );
00018   }
00019 
00020   for ( unsigned int j=0; j<Na; ++j ) {
00021     double diff = vnl_math_abs( p.angular(j) - q.angular(j) );
00022     if ( diff > vnl_math::pi ) {
00023       diff = 2*vnl_math::pi - diff;
00024     }
00025     sum_sq += vnl_math_sqr( diff );
00026   }
00027 
00028   return sum_sq;
00029 }
00030 
00031 
00032 double
00033 rsdl_dist( const rsdl_point& p, const rsdl_point& q )
00034 {
00035   return vcl_sqrt( rsdl_dist_sq( p, q ) );
00036 }
00037 
00038 
00039 double
00040 rsdl_dist_sq( const rsdl_point & p, const rsdl_bounding_box &  b )
00041 {
00042   double sum_sq = 0;
00043   unsigned int Nc = p.num_cartesian();
00044   unsigned int Na = p.num_angular();
00045   assert( Nc == b.num_cartesian() && Na == b.num_angular() );
00046 
00047   for ( unsigned int i=0; i<Nc; ++i ) {
00048     double x0 = b.min_cartesian(i), x1 = b.max_cartesian(i);
00049     double x = p.cartesian(i);
00050     if ( x < x0 ) {
00051       sum_sq += vnl_math_sqr( x0 - x );
00052     }
00053     else if ( x > x1 ) {
00054       sum_sq += vnl_math_sqr( x1 - x );
00055     }
00056   }
00057 
00058   for ( unsigned int j=0; j<Na; ++j ) {
00059     double a0 = b.min_angular(j), a1 = b.max_angular(j);
00060     double a = p.angular(j);
00061     if ( a0 > a1 ) {             // interval wraps around 0
00062       if ( a < a0 && a > a1 ) {  // outside interval, calculate distance
00063         sum_sq += vnl_math_sqr( vnl_math_min( a0-a, a-a1 ) );
00064       }
00065     }
00066     else {                       // interval does not wrap around
00067       if ( a > a1 ) {            // a is above a1
00068         sum_sq += vnl_math_sqr( vnl_math_min( a - a1, 2 * vnl_math::pi + a0 - a ) );
00069       }
00070       else if ( a0 > a ) {       // a is below a0
00071         sum_sq += vnl_math_sqr( vnl_math_min( a0 - a, 2 * vnl_math::pi + a - a1 ) );
00072       }
00073     }
00074   }
00075 
00076   return sum_sq;
00077 }
00078 
00079 double
00080 rsdl_dist( const rsdl_point & p, const rsdl_bounding_box& b )
00081 {
00082   return vcl_sqrt( rsdl_dist_sq( p, b ) );
00083 }
00084 
00085 
00086 bool
00087 rsdl_dist_point_in_box( const rsdl_point & pt,
00088                         const rsdl_bounding_box & box )
00089 {
00090   unsigned int Nc = pt.num_cartesian();
00091   unsigned int Na = pt.num_angular();
00092   assert( Nc == box.num_cartesian() && Na == box.num_angular() );
00093 
00094   for ( unsigned int i=0; i<Nc; ++i ) {
00095     double x = pt.cartesian(i);
00096     if ( x < box.min_cartesian(i) || box.max_cartesian(i) < x )
00097       return false;
00098   }
00099 
00100   for ( unsigned int j=0; j<Na; ++j ) {
00101     double a = pt.angular(j);
00102     if ( box.min_angular(j) < box.max_angular(j) ) {
00103       if ( a < box.min_angular(j) || box.max_angular(j) < a )
00104         return false;
00105     }
00106     else {
00107       if ( a > box.max_angular(j) && a < box.min_angular(j) )
00108         return false;
00109     }
00110   }
00111 
00112   return true;
00113 }
00114 
00115 void
00116 rsdl_dist_box_relation( const rsdl_bounding_box & inner,
00117                         const rsdl_bounding_box & outer,
00118                         bool& inside,
00119                         bool& intersects )
00120 {
00121   unsigned int Nc = inner.num_cartesian();
00122   unsigned int Na = inner.num_angular();
00123   assert( Nc == outer.num_cartesian() && Na == outer.num_angular() );
00124   inside = intersects = true;
00125 
00126   for ( unsigned int i=0; i<Nc && intersects; ++i ) {
00127     double x0 = inner.min_cartesian(i), x1 = inner.max_cartesian(i);
00128     double y0 = outer.min_cartesian(i), y1 = outer.max_cartesian(i);
00129 
00130     if ( x0 < y0 || y1 < x1 )
00131       inside = false;
00132 
00133     if ( y1 < x0 || x1 < y0 )
00134       intersects = false;
00135   }
00136 
00137   for ( unsigned int j=0; j<Na && intersects; ++j ) {
00138     double r0 = inner.min_angular(j), r1 = inner.max_angular(j);
00139     double s0 = outer.min_angular(j), s1 = outer.max_angular(j);
00140 
00141     if ( s0 <= s1 ) {    // outer angular interval doesn't wrap
00142       if ( r0 <= r1 ) {  // inner angular interval doesn't wrap
00143         if ( r0 < s0 || s1 < r1 )   // part of inner interval is outside
00144           inside = false;
00145         if ( r1 < s0 || r0 > s1 )   // all of inner interval is to the left or to the right
00146           intersects = false;
00147       }
00148       else {             //  inner angular interval does wrap
00149         inside = false;            // point of wrap-around is in inner but not in outer
00150         if ( r1 < s0 && s1 < r0 )
00151           intersects = false;
00152       }
00153     }
00154     else {               // outer angular interval does wrap
00155       if ( r0 <= r1 ) {  // inner angular interval doesn't wrap
00156         if ( r1 > s1 && r0 < s0 )
00157           inside = false;
00158         if ( r0 > s1 && r1 < s0 )
00159           intersects = false;
00160       }
00161       else {             // inner angular interval does wrap;  intersects must be true
00162         if ( r1 > s1 || r0 < s0 )
00163           inside = false;
00164       }
00165     }
00166   }
00167 }

Generated on Thu Jan 10 14:49:34 2008 for contrib/rpl/rsdl by  doxygen 1.4.4