Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gul_float.h

Go to the documentation of this file.
00001 #ifndef GUL_FLOAT_H
00002 #define GUL_FLOAT_H
00003 
00004 namespace gul {
00005 
00006 /*---------------------------------------------------------------------------
00007   check if two floating point numbers are approximately equal. in this check
00008   the relative error is measured.
00009   (  remark: according to knuth
00010           |a-b| <= eps*|b|  =>  a  ~  b  ('approximately rel_equal')
00011      and  |a-b| >  eps*|b|  =>  a !~~ b  (not 'essentialy rel_equal', for eps < 1
00012                                           & normalized floating point numbers)
00013      this check mixes both relations, 'approximately rel_equal' and 
00014      'essentialy rel_equal', so it isn't 100% correct!)
00015 -----------------------------------------------------------------------------*/
00016 template< class T >
00017 inline bool rel_equal( const T& a, const T& b, const T& eps )
00018 {
00019   return rtr<T>::fabs(a-b) <= rtr<T>::fabs(b) * eps; 
00020 }
00021 
00022 /*--------------------------------------------------------------------------
00023   check if two vectors are approximately equal. in this check
00024   the relative error is measured.
00025   ( remark: the maximum norm {..} is used to estimate the euclidian norm |..|
00026     by the equation:  {v} <= |v| <= {v}*sqrt(dim(v)) <= eps
00027     if this check succeeds, it is still possible that |v| <= eps < {v}*sqrt(dim),
00028     so this check isn't 100% correct!)
00029 ---------------------------------------------------------------------------*/
00030 template< class T >
00031 inline bool rel_equal( const gul::hpoint<T>& a, const gul::hpoint<T>& b, 
00032                    const T& eps )
00033 {
00034   T tol = eps / (T)2;
00035 
00036   if( !rel_equal(a.x, b.x, tol) ) return false;
00037   if( !rel_equal(a.y, b.y, tol) ) return false;
00038   if( !rel_equal(a.z, b.z, tol) ) return false;
00039   if( !rel_equal(a.w, b.w, tol) ) return false;
00040 
00041   return true;
00042 }
00043 
00044 template< class T >
00045 inline bool rel_equal( const gul::hpoint2<T>& a, const gul::hpoint2<T>& b, 
00046                    const T& eps )
00047 {
00048   T tol = eps / rtr<T>::root2_3();
00049 
00050   if( !rel_equal(a.x, b.x, tol) ) return false;
00051   if( !rel_equal(a.y, b.y, tol) ) return false;
00052   if( !rel_equal(a.w, b.w, tol) ) return false;
00053 
00054   return true;
00055 }
00056 
00057 template< class T >
00058 inline bool rel_equal( const gul::hpoint1<T>& a, const gul::hpoint1<T>& b, 
00059                    const T& eps )
00060 {
00061   T tol = eps / rtr<T>::root2_2();
00062 
00063   if( !rel_equal(a.x, b.x, tol) ) return false;
00064   if( !rel_equal(a.w, b.w, tol) ) return false;
00065 
00066   return true;
00067 }
00068 
00069 template< class T >
00070 inline bool rel_equal( const gul::point<T>& a, const gul::point<T>& b, 
00071                    const T& eps )
00072 {
00073   T tol = eps / rtr<T>::root2_3();
00074 
00075   if( !rel_equal(a.x, b.x, tol) ) return false;
00076   if( !rel_equal(a.y, b.y, tol) ) return false;
00077   if( !rel_equal(a.z, b.z, tol) ) return false;
00078 
00079   return true;
00080 }
00081 
00082 template< class T >
00083 inline bool rel_equal( const gul::point2<T>& a, const gul::point2<T>& b, 
00084                    const T& eps )
00085 {
00086   T tol = eps / rtr<T>::root2_2();
00087 
00088   if( !rel_equal(a.x, b.x, tol) ) return false;
00089   if( !rel_equal(a.y, b.y, tol) ) return false;
00090 
00091   return true;
00092 }
00093 
00094 template< class T >
00095 inline bool rel_equal( const gul::point1<T>& a, const gul::point1<T>& b, 
00096                    const T& eps )
00097 {
00098   T tol = eps;
00099 
00100   if( !rel_equal(a.x, b.x, tol) ) return false;
00101 
00102   return true;
00103 }
00104 
00105 /*-----------------------------------------------------------------------
00106   approximate normalization of a vector
00107 ------------------------------------------------------------------------*/
00108 template< class T >
00109 T max_norm( const point<T>& a ) 
00110 {
00111   T m;
00112 
00113   m = rtr<T>::fabs(a.x);
00114   if( rtr<T>::fabs(a.y) > m ) m = rtr<T>::fabs(a.y);
00115   if( rtr<T>::fabs(a.z) > m ) m = rtr<T>::fabs(a.z); 
00116   return m;
00117 }
00118 
00119 template< class T >
00120 T max_norm( const point2<T>& a ) 
00121 {
00122   T m;
00123 
00124   m = rtr<T>::fabs(a.x);
00125   if( rtr<T>::fabs(a.y) > m ) m = rtr<T>::fabs(a.y); 
00126   return m;
00127 }
00128 
00129 /*-----------------------------------------------------------------------
00130   check if the cross-product of two vectors is approximately zero
00131 ------------------------------------------------------------------------*/
00132 template< class T >
00133 bool zero_sine( const point<T>& ina, const point<T>& inb, const T& eps )
00134 {
00135   T la,lb;
00136   point<T> a,b;
00137 
00138   // normalize a,b (approximately)
00139   la = max_norm(ina);
00140   if( !la ) return true;
00141   a = ((T)1/la)*ina;
00142 
00143   lb = max_norm(inb);
00144   if( !lb ) return true;
00145   b = ((T)1/lb)*inb;
00146 
00147   if( rel_equal(a.y*b.z,b.y*a.z,eps) &&
00148       rel_equal(b.x*a.z,a.x*b.z,eps) &&
00149       rel_equal(a.x*b.y,b.x*a.y,eps) )
00150     return true;
00151 
00152   return false;
00153 }
00154 
00155 template< class T >
00156 bool zero_sine( const point2<T>& ina, const point2<T>& inb, const T& eps )
00157 {
00158   T la,lb;
00159 
00160   // normalize a,b (approximately)
00161   la = max_norm(a);
00162   if( !la ) return true;
00163   a = ((T)1/la)*ina;
00164 
00165   lb = max_norm(b);
00166   if( !lb ) return true;
00167   b = ((T)1/lb)*inb;
00168 
00169   if( rel_equal(a.x*b.y-b.x*a.y,eps) )
00170     return true;
00171 
00172   return false;
00173 }
00174 
00175 /*---------------------------------------------------------------------------
00176   check if two floating point numbers are approximately equal. in this check
00177   the absolute error is measured.
00178 -----------------------------------------------------------------------------*/
00179 template< class T >
00180 inline bool abs_equal( const T& a, const T& b, const T& eps )
00181 {
00182   return rtr<T>::fabs(a-b) <= eps; 
00183 }
00184 
00185 /*--------------------------------------------------------------------------
00186   check if two vectors are approximately equal. in this check
00187   the absolute error is measured.
00188   ( remark: the maximum norm {..} is used to estimate the euclidian norm |..|
00189     by the equation:  {v} <= |v| <= {v}*sqrt(dim(v)) <= eps
00190     if this check succeeds, it is still possible that |v| <= eps < {v}*sqrt(dim),
00191     so this check isn't 100% correct!)
00192 ---------------------------------------------------------------------------*/
00193 template< class T >
00194 inline bool abs_equal( const gul::hpoint<T>& a, const gul::hpoint<T>& b, 
00195                        const T& eps )
00196 {
00197   T tol = eps / (T)2;
00198 
00199   if( !abs_equal(a.x, b.x, tol) ) return false;
00200   if( !abs_equal(a.y, b.y, tol) ) return false;
00201   if( !abs_equal(a.z, b.z, tol) ) return false;
00202   if( !abs_equal(a.w, b.w, tol) ) return false;
00203 
00204   return true;
00205 }
00206 
00207 template< class T >
00208 inline bool abs_equal( const gul::hpoint2<T>& a, const gul::hpoint2<T>& b, 
00209                    const T& eps )
00210 {
00211   T tol = eps / rtr<T>::root2_3();
00212 
00213   if( !abs_equal(a.x, b.x, tol) ) return false;
00214   if( !abs_equal(a.y, b.y, tol) ) return false;
00215   if( !abs_equal(a.w, b.w, tol) ) return false;
00216 
00217   return true;
00218 }
00219 
00220 template< class T >
00221 inline bool abs_equal( const gul::hpoint1<T>& a, const gul::hpoint1<T>& b, 
00222                    const T& eps )
00223 {
00224   T tol = eps / rtr<T>::root2_2();
00225 
00226   if( !abs_equal(a.x, b.x, tol) ) return false;
00227   if( !abs_equal(a.w, b.w, tol) ) return false;
00228 
00229   return true;
00230 }
00231 
00232 template< class T >
00233 inline bool abs_equal( const gul::point<T>& a, const gul::point<T>& b, 
00234                    const T& eps )
00235 {
00236   T tol = eps / rtr<T>::root2_3();
00237 
00238   if( !abs_equal(a.x, b.x, tol) ) return false;
00239   if( !abs_equal(a.y, b.y, tol) ) return false;
00240   if( !abs_equal(a.z, b.z, tol) ) return false;
00241 
00242   return true;
00243 }
00244 
00245 template< class T >
00246 inline bool abs_equal( const gul::point2<T>& a, const gul::point2<T>& b, 
00247                    const T& eps )
00248 {
00249   T tol = eps / rtr<T>::root2_2();
00250 
00251   if( !abs_equal(a.x, b.x, tol) ) return false;
00252   if( !abs_equal(a.y, b.y, tol) ) return false;
00253 
00254   return true;
00255 }
00256 
00257 template< class T >
00258 inline bool abs_equal( const gul::point1<T>& a, const gul::point1<T>& b, 
00259                    const T& eps )
00260 {
00261   T tol = eps;
00262 
00263   if( !abs_equal(a.x, b.x, tol) ) return false;
00264 
00265   return true;
00266 }
00267 
00268 
00269 }
00270 
00271 #endif
00272 
00273 
00274 #if 0
00275 ##################################################################################
00276   OLD STUFF
00277 ##################################################################################
00278 
00279 
00280 /*
00281 template< class T >
00282 inline bool equal( const T& a, const T& b, const T& eps )
00283 {
00284   T scaled = rtr<T>::fabs(a-b)/ 
00285              rtr<T>::scalbn( (T)1,
00286                Max( rtr<T>::ilogb(rtr<T>::fabs(a)),
00287                     rtr<T>::ilogb(rtr<T>::fabs(b))) );
00288   return  scaled <= eps;
00289 }
00290 
00291 template< class T >
00292 inline bool equal( const T& a, const T& b, const T& eps, T& scaled )
00293 {
00294   scaled = rtr<T>::fabs(a-b)/ 
00295            rtr<T>::scalbn( (T)1,
00296              Max( rtr<T>::ilogb(rtr<T>::fabs(a)),
00297                   rtr<T>::ilogb(rtr<T>::fabs(b))) );
00298   return  scaled <= eps;
00299 }
00300 */
00301 
00302 /*
00303 bool strongly_equal( const T& a, const T& b, const T& eps )
00304 {
00305   T diff = rtr<T>::fabs(a-b);
00306   return (diff/rtr<T>::fabs(a) < eps) && (diff/rtr<T>::fabs(b) < eps);
00307 }
00308 
00309 bool greater( const T& a, const T& b, const T& eps )
00310 {
00311   T diff = a-b;
00312   return (diff/rtr<T>::fabs(a) > eps) && (diff/rtr<T>::fabs(b) > eps);
00313 }
00314 
00315 bool lower( const T& a, const T& b, const T& eps )
00316 {
00317   T diff = b-a;
00318   return (diff/rtr<T>::fabs(a) > eps) && (diff/rtr<T>::fabs(b) > eps);
00319 }
00320 */
00321 
00322 ##################################################################
00323 
00324                                  /* -- check, if vector is (almost) zero --- */
00325 /*
00326 template< class T >
00327 inline bool is_zero( const point<T>& a, const rtl<T>& t )
00328 {
00329   T x,y,z;
00330 
00331   x = rtr<T>::fabs(a.x);
00332   if( x > t.zero_tol ) return false;
00333   y = rtr<T>::fabs(a.y);
00334   if( y > t.zero_tol ) return false;    
00335   z = rtr<T>::fabs(a.z);
00336   if( z > t.zero_tol ) return false;
00337     
00338   if( (x <= t.zero_tol_v3) && (y <= t.zero_tol_v3) && 
00339       (z <= t.zero_tol_v3) )
00340     return true;
00341 
00342   if( rtr<T>::sqrt(x*x + y*y + z*z) > t.zero_tol ) return false;
00343 
00344   return true;
00345 }
00346 template< class T >
00347 inline bool is_zero( const point2<T>& a, const rtl<T>& t )
00348 {
00349   T x,y;
00350 
00351   x = rtr<T>::fabs(a.x);
00352   if( x > t.zero_tol ) return false;
00353   y = rtr<T>::fabs(a.y);
00354   if( y > t.zero_tol ) return false;    
00355   
00356   if( (x <= t.zero_tol_v2) && (y <= t.zero_tol_v2) ) 
00357     return true;
00358 
00359   if( rtr<T>::sqrt(x*x + y*y) > t.zero_tol ) return false;
00360 
00361   return true;
00362 }
00363 */
00364 
00365      /* check, if the difference of two homogeneous vectors is (almost) zero */
00366 /*
00367 template< class T >
00368 inline bool dist_is_zero( const hpoint<T>& a, const hpoint<T>& b,
00369                           const rtl<T>& t )
00370 {
00371   T x,y,z,w;
00372   
00373   if( !equal(a.x, b.x, t.zero_tol, x) ) return false;
00374   if( !equal(a.y, b.y, t.zero_tol, y) ) return false;
00375   if( !equal(a.z, b.z, t.zero_tol, z) ) return false;
00376   if( !equal(a.w, b.w, t.zero_tol, w) ) return false;
00377 */
00378   /*
00379   x = rtr<T>::fabs(a.x-b.x);
00380   if( x > t.zero_tol ) return false;
00381   y = rtr<T>::fabs(a.y-b.y);
00382   if( y > t.zero_tol ) return false;    
00383   z = rtr<T>::fabs(a.z-b.z);
00384   if( z > t.zero_tol ) return false;
00385   w = rtr<T>::fabs(a.w-b.w);
00386   if( w > t.zero_tol ) return false;
00387 
00388   if( (x <= t.zero_tol_v4) && (y <= t.zero_tol_v4) &&
00389       (z <= t.zero_tol_v4) && (w <= t.zero_tol_v4) )
00390     return true;
00391 
00392   if( rtr<T>::sqrt( x*x + y*y + z*z + w*w ) > t.zero_tol ) return false;
00393   */
00394 /*
00395   return true;      
00396 }
00397 */
00398    /* check, if the difference of two homogeneous vectors has a greater length
00399       than tol. */
00400 /*
00401 template< class T >
00402 inline bool dist_longer_than( const hpoint<T>& a, const hpoint<T>& b, 
00403                               const T tolerance )
00404 {
00405   T x,y,z,w;
00406 
00407   if( !equal(a.x, b.x, tolerance, x) ) return true;
00408   if( !equal(a.y, b.y, tolerance, y) ) return true;
00409   if( !equal(a.z, b.z, tolerance, z) ) return true;
00410   if( !equal(a.w, b.w, tolerance, w) ) return true;
00411 */
00412   /*
00413   x = rtr<T>::fabs(a.x-b.x);
00414   if( x > tolerance ) return true;
00415   y = rtr<T>::fabs(a.y-b.y);
00416   if( y > tolerance ) return true;    
00417   z = rtr<T>::fabs(a.z-b.z);
00418   if( z > tolerance ) return true;
00419   w = rtr<T>::fabs(a.w-b.w);
00420   if( w > tolerance ) return true;
00421 
00422   tol_v4 = tolerance / (T)2;  // sqrt(4)=2
00423 
00424   if( (x <= tol_v4) && (y <= tol_v4) && 
00425       (z <= tol_v4) && (w <= tol_v4) ) 
00426     return false;
00427   
00428   if( rtr<T>::sqrt(x*x + y*y + z*z + w*w) > tolerance ) return true;
00429   */
00430 /*
00431   return false;  
00432 }
00433 */
00434 
00435 /*
00436 template< class T >
00437 inline bool dist_longer_than( const hpoint2<T>& a, const hpoint2<T>& b, 
00438                               const T tolerance )
00439 {
00440   T x,y,w;
00441 
00442   if( !equal(a.x, b.x, tolerance, x) ) return true;
00443   if( !equal(a.y, b.y, tolerance, y) ) return true;
00444   if( !equal(a.w, b.w, tolerance, w) ) return true;
00445 */
00446   /*
00447   x = rtr<T>::fabs(a.x-b.x);
00448   if( x > tolerance ) return true;
00449   y = rtr<T>::fabs(a.y-b.y);
00450   if( y > tolerance ) return true;    
00451   w = rtr<T>::fabs(a.w-b.w);
00452   if( w > tolerance ) return true;
00453 
00454   tol_v3 = tolerance / rtr<T>::root2_3();
00455 
00456   if( (x <= tol_v3) && (y <= tol_v3) && (w <= tol_v3) ) 
00457     return false;
00458   
00459   if( rtr<T>::sqrt(x*x + y*y + w*w) > tolerance ) return true;
00460   */
00461 /*
00462   return false;  
00463 }
00464 */
00465                   /* check, if a vector has a greater length than tolerance */
00466 /*
00467 template< class T >
00468 inline bool longer_than( const point<T>& a, const T tolerance )
00469 {
00470   T x,y,z,tol_v3;
00471 
00472   x = rtr<T>::fabs(a.x);
00473   if( x > tolerance ) return true;
00474   y = rtr<T>::fabs(a.y);
00475   if( y > tolerance ) return true;    
00476   z = rtr<T>::fabs(a.z);
00477   if( z > tolerance ) return true;
00478 
00479   tol_v3 = tolerance / rtr<T>::root2_3();
00480 
00481   if( (x <= tol_v3) && (y <= tol_v3) && (z <= tol_v3) ) return false;
00482   
00483   if( rtr<T>::sqrt(x*x + y*y + z*z) > tolerance ) return true;
00484 
00485   return false;  
00486 }
00487 template< class T >
00488 inline bool longer_than( const point2<T>& a, const T tolerance )
00489 {
00490   T x,y,tol_v2;
00491 
00492   x = rtr<T>::fabs(a.x);
00493   if( x > tolerance ) return true;
00494   y = rtr<T>::fabs(a.y);
00495   if( y > tolerance ) return true;    
00496 
00497   tol_v2 = tolerance / rtr<T>::root2_2();
00498 
00499   if( (x <= tol_v2) && (y <= tol_v2) ) return false;
00500   
00501   if( rtr<T>::sqrt(x*x + y*y) > tolerance ) return true;
00502 
00503   return false;  
00504 }
00505 */
00506    /* check, if the difference of two vectors has a greater length than tol. */
00507 /*
00508 template< class T >
00509 inline bool dist_longer_than( const point<T>& a, const point<T>& b, 
00510                               const T tolerance )
00511 {
00512   T x,y,z;
00513 
00514   if( !equal(a.x, b.x, tolerance, x) ) return true;
00515   if( !equal(a.y, b.y, tolerance, y) ) return true;
00516   if( !equal(a.z, b.z, tolerance, z) ) return true;
00517 */
00518   /*
00519   x = rtr<T>::fabs(a.x-b.x);
00520   if( x > tolerance ) return true;
00521   y = rtr<T>::fabs(a.y-b.y);
00522   if( y > tolerance ) return true;    
00523   z = rtr<T>::fabs(a.z-b.z);
00524   if( z > tolerance ) return true;
00525 
00526   tol_v3 = tolerance / rtr<T>::root2_3();
00527 
00528   if( (x <= tol_v3) && (y <= tol_v3) && (z <= tol_v3) ) return false;
00529   
00530   if( rtr<T>::sqrt(x*x + y*y + z*z) > tolerance ) return true;
00531   */
00532 /*
00533   return false;  
00534 }
00535 */
00536 
00537 /*
00538 template< class T >
00539 inline bool dist_longer_than( const point2<T>& a, const point2<T>& b, 
00540                               const T tolerance )
00541 {
00542   T x,y;
00543 
00544   if( !equal(a.x, b.x, tolerance, x) ) return true;
00545   if( !equal(a.y, b.y, tolerance, y) ) return true;
00546 */
00547   /*
00548   x = rtr<T>::fabs(a.x-b.x);
00549   if( x > tolerance ) return true;
00550   y = rtr<T>::fabs(a.y-b.y);
00551   if( y > tolerance ) return true;    
00552 
00553   tol_v2 = tolerance / rtr<T>::root2_2();
00554 
00555   if( (x <= tol_v2) && (y <= tol_v2) ) return false;
00556   
00557   if( rtr<T>::sqrt(x*x + y*y) > tolerance ) return true;
00558   */
00559 /*
00560   return false;  
00561 }
00562 */
00563 
00564 ################################################################################
00565 #endif
00566 

Generated on Mon Jan 21 04:17:32 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001