00001 #include <esg/spacesorting/FDH14DistRot.h>
00002
00003 using namespace esg;
00004
00005
00006
00007
00008
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
00019
00020
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
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