FDH14DistRot.cc

Go to the documentation of this file.
00001 #include <esg/spacesorting/FDH14DistRot.h>
00002 
00003 using namespace esg;
00004 
00005 
00006 /*
00007  * This macro returns one direction of rotated FDH, it uses "cache" of
00008  * previously computed values
00009  */
00010 #define _B(x) ((_set & (1<<(x))) \
00011                ? (_transf[x]) \
00012                : ((_set |= (1<<(x))), \
00013                   ((_pRotInfo) \
00014                    ? (_transf[x]=FDH14::RotInfo::fast_lp(_pRotInfo->get(x),_orig)) \
00015                    : (_transf[x]=_orig[x]))))
00016 
00017 /*
00018  * Update current minimal value;
00019  * in case it drops below "bound" we cannot improve current result;
00020  * there can be at most one direction from each pair with value below zero
00021  */
00022 #define _UPDATE(i, x) { \
00023     register float s=(x); \
00024     if (s<minim) { if (s<=bound) return MAXFLOAT; minim=s; index=(i); } \
00025     if (s<0) continue; \
00026 }
00027 
00028 double FDH14DistRot::_distance(const FDH14& fdh14, double minD, Vector3* pDir)
00029 {
00030     register float    minim = FLT_MAX;
00031     register float    bound = -minD;
00032     register unsigned index = 0;
00033 
00034     for (register unsigned i = 0; i < FDH14::DIRS; i++) {
00035         _UPDATE(i, fdh14._values[i]             + _B(i+FDH14::DIRS));
00036         _UPDATE(i, fdh14._values[i+FDH14::DIRS] + _B(i));
00037     }
00038 
00039     if (pDir) pDir->set(FDH14::FDHMat[index][0],
00040                         FDH14::FDHMat[index][1],
00041                         FDH14::FDHMat[index][2]);
00042 
00043     return ((_scaleRatio == 0.) ? -MAXFLOAT : -minim / _scaleRatio);
00044 }
00045 
00046 double FDH14DistRot::_distance(const Geometry& geom, double minD,Vector3* pDir)
00047 {
00048     register float    minim = FLT_MAX;
00049     register float    bound = -minD;
00050     register unsigned index = 0;
00051     Interval          ext;
00052 
00053     minim = MAXFLOAT;
00054     bound = -minD;
00055 
00056     for (unsigned i = 0; i < FDH14::DIRS; i++) {
00057         ext = geom.extent(FDH14::FDHMat[i][0],
00058                           FDH14::FDHMat[i][1],
00059                           FDH14::FDHMat[i][2]);
00060         _UPDATE(i,  ext.max + _B(i+FDH14::DIRS));
00061         _UPDATE(i, -ext.min + _B(i));
00062     }
00063 
00064     if (pDir) pDir->set(FDH14::FDHMat[index][0],
00065                         FDH14::FDHMat[index][1],
00066                         FDH14::FDHMat[index][2]);
00067 
00068     return ((_scaleRatio == 0.) ? -MAXFLOAT : -minim / _scaleRatio);
00069 }
00070 
00071 bool FDH14DistRot::_separation(const FDH14& fdh14)
00072 {
00073     for (unsigned i = 0; i < FDH14::DIRS; i++) {
00074         if ((fdh14._values[i]            +_B(i+FDH14::DIRS)) < 0) return true;
00075         if ((fdh14._values[i+FDH14::DIRS]+_B(i))             < 0) return true;
00076     }
00077 
00078     return false;
00079 }
00080 
00081 bool FDH14DistRot::_separation(const Geometry& geom)
00082 {
00083     Interval ext;
00084 
00085     for (unsigned i = 0; i < FDH14::DIRS; i++) {
00086         ext = geom.extent(FDH14::FDHMat[i][0],
00087                           FDH14::FDHMat[i][1],
00088                           FDH14::FDHMat[i][2]);
00089         if (( ext.max + _B(i+FDH14::DIRS)) < 0) return true;
00090         if ((-ext.min + _B(i))             < 0) return true;
00091     }
00092 
00093     return false;
00094 }
00095 
00096 
00097 #undef _B
00098 #undef _UPDATE
00099 
00100 
00101 FDH14DistRot::FDH14DistRot(float          * fdhValues,
00102                            FDH14::RotInfo * pRotInfo,
00103                            double           sr)
00104     : DistRot(sr)
00105 {
00106     _orig     = fdhValues;
00107     _set      = 0;
00108     _pRotInfo = pRotInfo;
00109     _transf   = new float [FDH14::SIZE];
00110 }
00111 
00112 double FDH14DistRot::distance(Geometry& geom, double minD, Vector3* pDir)
00113 {
00114     if (!_orig) return MAXFLOAT;
00115 
00116     try {
00117         FDH14& fdh = dynamic_cast<FDH14&>(geom);
00118         return _distance(fdh, minD, pDir);
00119     } catch (bad_cast) { 
00120         try {
00121             FDH& fdh = dynamic_cast<FDH&>(geom);
00122             return _distance(fdh, minD, pDir);
00123         } catch (bad_cast) { 
00124             return _distance(geom, minD, pDir);
00125         }
00126     }
00127 }
00128 
00129 bool FDH14DistRot::separation(Geometry& geom, Vector3* pDir)
00130 {
00131     // we are able to compute the direction only in distance() method
00132     if (pDir) return ((distance(geom, FLT_MAX, pDir) > 0.) ? true : false);
00133     
00134     if (!_orig) return true;
00135 
00136     try {
00137         FDH14& fdh = dynamic_cast<FDH14&>(geom);
00138         return _separation(fdh);
00139     } catch (bad_cast) { 
00140         try {
00141             FDH& fdh = dynamic_cast<FDH&>(geom);
00142             return _separation(fdh);
00143         } catch (bad_cast) { 
00144             return _separation(geom);
00145         }
00146     }
00147 }
00148 
00149 

Generated on Wed Jun 28 12:24:29 2006 for esg by  doxygen 1.4.6