00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <time.h>
00025 #include <vcg/space/distance2.h>
00026 #include<vcg/space/segment2.h>
00027 #include<vcg/space/index/grid_static_ptr2d.h>
00028 #include<vcg/space/index/grid_closest2d.h>
00029 #include<vcg/space/intersection2.h>
00030
00031 typedef double MyScalarType;
00032 typedef vcg::Point2<MyScalarType> MyCoordType;
00033 typedef vcg::Ray2<MyScalarType> MyRayType;
00034
00035
00036 class MySegmentType:public vcg::Segment2<MyScalarType>
00037 {
00038 public:
00039 int mark;
00040 bool IsD(){return false;}
00041
00042 MySegmentType(const vcg::Point2<MyScalarType> &_P0,
00043 const vcg::Point2<MyScalarType> &_P1)
00044 {
00045 P0()=_P0;
00046 P1()=_P1;
00047 mark=0;
00048 }
00049
00050 int &TMark(){return mark;}
00051
00052 MySegmentType(){}
00053
00054 MySegmentType(const MySegmentType &s1):vcg::Segment2<MyScalarType>(s1)
00055 {
00056 P0()=s1.P0();
00057 P1()=s1.P1();
00058 mark=s1.mark;
00059 }
00060 };
00061
00062
00063
00064 std::vector<MySegmentType> AllocatedSeg;
00065
00066
00067
00068 vcg::Point2<MyScalarType> RandomPoint(MyScalarType SpaceSize=100)
00069 {
00070 int dimension=RAND_MAX;
00071 int X=rand();
00072 int Y=rand();
00073 vcg::Point2<MyScalarType> P0=vcg::Point2<MyScalarType>((MyScalarType)X/dimension,(MyScalarType)Y/dimension);
00074 P0*=SpaceSize;
00075 return P0;
00076 }
00077
00078
00079 void RandomSeg(vcg::Point2<MyScalarType> &P0,
00080 vcg::Point2<MyScalarType> &P1,
00081 MyScalarType SpaceSize=100,
00082 MyScalarType maxdim=1)
00083 {
00084
00085 P0=RandomPoint(SpaceSize);
00086 vcg::Point2<MyScalarType> D=RandomPoint(SpaceSize);
00087 D.Normalize();
00088 D*=maxdim;
00089 P1=P0+D;
00090 }
00091
00092 void InitRandom(int num,
00093 MyScalarType SpaceSize=100,
00094 MyScalarType maxdim=1)
00095 {
00096 AllocatedSeg.clear();
00097 AllocatedSeg.resize(num);
00098 srand(clock());
00099 for (int i=0;i<num;i++)
00100 {
00101 vcg::Point2<MyScalarType> P0,P1;
00102 RandomSeg(P0,P1,SpaceSize,maxdim);
00103 AllocatedSeg[i]=MySegmentType(P0,P1);
00104
00105 }
00106
00107 }
00108
00109
00110
00111 class MyMarker
00112 {
00113
00114 public:
00115 int mark;
00116
00117 MyMarker(){mark=0;}
00118
00119 void UnMarkAll(){mark++;}
00120
00121 bool IsMarked(MySegmentType* obj)
00122 {
00123 int markObj=obj->TMark();
00124 return(markObj==mark);
00125 }
00126
00127 void Mark(MySegmentType* obj)
00128 {obj->TMark()=mark;}
00129
00130 };
00131
00132
00133 MyMarker mf;
00134 vcg::GridStaticPtr2D<MySegmentType,MyScalarType> Grid2D;
00135
00136
00137 MySegmentType * GetClosestSegment(MyCoordType & _p,
00138 MyCoordType &_closestPt)
00139 {
00140 vcg::PointSegment2DEPFunctor<MyScalarType> PDistFunct;
00141
00142 MyScalarType _minDist;
00143 MyScalarType _maxDist=std::numeric_limits<MyScalarType>::max();
00144 return (Grid2D.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
00145 }
00146
00147 void GetInBoxSegments(vcg::Box2<MyScalarType> bbox,std::vector<MySegmentType*> &result)
00148 {
00149 Grid2D.GetInBox(mf,bbox,result);
00150 }
00151
00152 MySegmentType * DoRay(MyRayType & _r,
00153 MyCoordType &_closestPt)
00154 {
00155 MyRayType _ray1=_r;
00156 _ray1.Normalize();
00157 typedef vcg::RaySegmentIntersectionFunctor SintFunct;
00158 SintFunct rs;
00159 MyScalarType _maxDist=std::numeric_limits<MyScalarType>::max();
00160 MyScalarType _t;
00161 MySegmentType *seg=Grid2D.DoRay(rs,mf,_ray1,_maxDist,_t);
00162
00163 if (seg==NULL)return NULL;
00164 _closestPt=_ray1.Origin()+_ray1.Direction()*_t;
00165 return seg;
00166 }
00167
00168
00169 void GetInBoxSegmentsBruteF( vcg::Box2<MyScalarType> bbox,
00170 std::vector<MySegmentType*> &result)
00171 {
00172 for (size_t i=0;i<AllocatedSeg.size();i++)
00173 {
00174 if (!AllocatedSeg[i].BBox().Collide(bbox))continue;
00175 result.push_back(&AllocatedSeg[i]);
00176 }
00177 }
00178
00179 MySegmentType* GetClosesestSegmentBruteF(MyCoordType & _p,
00180 MyCoordType &_closestPt)
00181 {
00182 MyScalarType _minDist=std::numeric_limits<MyScalarType>::max();
00183 MySegmentType *ret=NULL;
00184 for (size_t i=0;i<AllocatedSeg.size();i++)
00185 {
00186 vcg::Point2<MyScalarType> test;
00187 test=vcg::ClosestPoint(AllocatedSeg[i],_p);
00188 MyScalarType currD=(test-_p).Norm();
00189 if (currD<_minDist)
00190 {
00191 _closestPt=test;
00192 _minDist=currD;
00193 ret=&AllocatedSeg[i];
00194 }
00195 }
00196 return ret;
00197 }
00198
00199 MySegmentType * DoRayBruteF(MyRayType & _r,
00200 MyCoordType &_closestPt)
00201 {
00202 MyScalarType _minDist=std::numeric_limits<MyScalarType>::max();
00203 MySegmentType *ret=NULL;
00204 for (size_t i=0;i<AllocatedSeg.size();i++)
00205 {
00206 vcg::Point2<MyScalarType> test;
00207 bool inters=vcg::RaySegmentIntersection(_r,AllocatedSeg[i],test);
00208 if (!inters)continue;
00209 MyScalarType currD=(test-_r.Origin()).Norm();
00210 if (currD<_minDist)
00211 {
00212 _closestPt=test;
00213 _minDist=currD;
00214 ret=&AllocatedSeg[i];
00215 }
00216 }
00217 return ret;
00218 }
00219
00220
00221 void TestBox(int num_test=100000,
00222 MyScalarType SpaceSize=100)
00223 {
00224 int numWrong=0;
00225
00226 for (int i=0;i<num_test;i++)
00227 {
00228 vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
00229 vcg::Point2<MyScalarType> P1=RandomPoint(SpaceSize);
00230 vcg::Box2<MyScalarType> bbox;
00231 bbox.Add(P0);
00232 bbox.Add(P1);
00233 std::vector<MySegmentType*> result0;
00234 GetInBoxSegments(bbox,result0);
00235
00236 std::vector<MySegmentType*> result1;
00237 GetInBoxSegmentsBruteF(bbox,result1);
00238
00239 std::sort(result0.begin(),result0.end());
00240 std::sort(result1.begin(),result1.end());
00241
00242 std::vector<MySegmentType*>::iterator new_end=std::unique(result1.begin(),result1.end());
00243 int dist=distance(result1.begin(),new_end);
00244 result1.resize(dist);
00245
00246 if (result0.size()!=result1.size())numWrong++;
00247
00248 for (size_t j = 0; j < result0.size(); j++)
00249 if (result0[j] != result1[j])
00250 {
00251 numWrong++;
00252 }
00253 }
00254 printf("WRONG TESTS BBOX %d ON %d \n",numWrong,num_test);
00255 fflush(stdout);
00256 }
00257
00258 void TestClosest(int num_test=100000,
00259 MyScalarType SpaceSize=100)
00260 {
00261
00262 int numWrong=0;
00263 for (int i=0;i<num_test;i++)
00264 {
00265 vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
00266
00267 vcg::Point2<MyScalarType> closest0;
00268 MySegmentType* result0=GetClosestSegment(P0,closest0);
00269
00270 vcg::Point2<MyScalarType> closest1;
00271 MySegmentType* result1=GetClosesestSegmentBruteF(P0,closest1);
00272
00273
00274 if (result0!=result1)
00275 {
00276 numWrong++;
00277 printf("D0 %5.5f \n",(closest0-P0).Norm());
00278 printf("D1 %5.5f \n",(closest1-P0).Norm());
00279 fflush(stdout);
00280 }
00281 }
00282 printf("WRONG TESTS CLOSEST %d ON %d \n",numWrong,num_test);
00283 fflush(stdout);
00284 }
00285
00286 void TestRay(int num_test=100000,
00287 MyScalarType SpaceSize=100)
00288 {
00289 int numWrong=0;
00290 int NUll0=0;
00291 int NUll1=0;
00292 for (int i=0;i<num_test;i++)
00293 {
00294 vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
00295 vcg::Point2<MyScalarType> P1=RandomPoint(SpaceSize);
00296 vcg::Point2<MyScalarType> Orig=P0;
00297 vcg::Point2<MyScalarType> Dir=P1-P0;
00298 Dir.Normalize();
00299
00300 MyRayType r(Orig,Dir);
00301
00302 vcg::Point2<MyScalarType> closest0;
00303 MySegmentType* result0=DoRay(r,closest0);
00304
00305 vcg::Point2<MyScalarType> closest1;
00306 MySegmentType* result1=DoRayBruteF(r,closest1);
00307
00308
00309 if (result0!=result1)
00310 {
00311 numWrong++;
00312
00313
00314
00315 }
00316 if (result0==NULL) NUll0++;
00317 if (result1==NULL) NUll1++;
00318 }
00319 printf("WRONG TESTS DORAY %d ON %d \n",numWrong,num_test);
00320 printf("NULL0 %d \n",NUll0);
00321 printf("NULL1 %d \n",NUll1);
00322 fflush(stdout);
00323 }
00324
00325 int main( int argc, char **argv )
00326 {
00327 (void) argc;
00328 (void) argv;
00329 int num_sample=20000;
00330 int t0=clock();
00331
00332 printf("** Random Initialization ** \n");
00333 fflush(stdout);
00334 InitRandom(num_sample,100,0.3);
00335 int t1=clock();
00336
00338 printf("** Time elapsed for initialization of %d sample is %d\n \n",num_sample,t1-t0);
00339 Grid2D.Set(AllocatedSeg.begin(),AllocatedSeg.end());
00340 fflush(stdout);
00341
00342
00343 TestBox(num_sample);
00344 TestClosest(num_sample);
00345 TestRay(num_sample);
00346
00347 return 0;
00348 }