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 ) {
00062 if ( a < a0 && a > a1 ) {
00063 sum_sq += vnl_math_sqr( vnl_math_min( a0-a, a-a1 ) );
00064 }
00065 }
00066 else {
00067 if ( a > a1 ) {
00068 sum_sq += vnl_math_sqr( vnl_math_min( a - a1, 2 * vnl_math::pi + a0 - a ) );
00069 }
00070 else if ( a0 > a ) {
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 ) {
00142 if ( r0 <= r1 ) {
00143 if ( r0 < s0 || s1 < r1 )
00144 inside = false;
00145 if ( r1 < s0 || r0 > s1 )
00146 intersects = false;
00147 }
00148 else {
00149 inside = false;
00150 if ( r1 < s0 && s1 < r0 )
00151 intersects = false;
00152 }
00153 }
00154 else {
00155 if ( r0 <= r1 ) {
00156 if ( r1 > s1 && r0 < s0 )
00157 inside = false;
00158 if ( r0 > s1 && r1 < s0 )
00159 intersects = false;
00160 }
00161 else {
00162 if ( r1 > s1 || r0 < s0 )
00163 inside = false;
00164 }
00165 }
00166 }
00167 }