diff --git a/apps/sample/hashing_2D/test_hash2D.cpp b/apps/sample/hashing_2D/test_hash2D.cpp index 5fad4feb..e480c6f0 100644 --- a/apps/sample/hashing_2D/test_hash2D.cpp +++ b/apps/sample/hashing_2D/test_hash2D.cpp @@ -22,56 +22,32 @@ ****************************************************************************/ #include #include -#include #include -#include +#include +#include +#include #include typedef double MyScalarType; +typedef vcg::Point2 MyCoordType; +typedef vcg::Ray2 MyRayType; +//**BASIC SEGMENT CLASS class MySegmentType:public vcg::Segment2 { public: int mark; - bool deleted; - bool IsD(){return deleted;} - typedef vcg::Point2 CoordType; + bool IsD(){return false;} - MySegmentType(const vcg::Point2 &_P0, - const vcg::Point2 &_P1) - { - P0()=_P0; - P1()=_P1; + MySegmentType(const vcg::Point2 &_P0, + const vcg::Point2 &_P1) + { + P0()=_P0; + P1()=_P1; mark=0; } - void GetBBox(vcg::Box2 &BB2) - { - //BB2.SetNull(); - BB2.Set(P0()); - BB2.Add(P1()); - } - - void GetSubBBox(const ScalarType &step_size, - std::vector > &RasterBox) - { - //RasterBox.clear(); - ScalarType lenght=(P1()-P0()).Norm(); - CoordType dir=(P1()-P0()); - dir.Normalize(); - int steps= (int)ceil(lenght/(ScalarType)step_size); - RasterBox.resize(steps); - - CoordType currP0=P0(); - CoordType currP1; - for (int i=0;i(currP0,currP1)); - currP0=currP1; - } - RasterBox[steps-1]=(vcg::Box2(currP0,P1())); - } + int &TMark(){return mark;} MySegmentType(){} @@ -80,10 +56,57 @@ public: P0()=s1.P0(); P1()=s1.P1(); mark=s1.mark; - deleted=s1.deleted; } }; + +//**ALLOCATED SEGMENTS**// +std::vector AllocatedSeg; + +//**GENERATION OF RANDOM SEGMENTS + +vcg::Point2 RandomPoint(MyScalarType SpaceSize=100) +{ + int dimension=RAND_MAX; + int X=rand(); + int Y=rand(); + vcg::Point2 P0=vcg::Point2((MyScalarType)X/dimension,(MyScalarType)Y/dimension); + P0*=SpaceSize; + return P0; +} + + +void RandomSeg(vcg::Point2 &P0, + vcg::Point2 &P1, + MyScalarType SpaceSize=100, + MyScalarType maxdim=1) +{ + + P0=RandomPoint(SpaceSize); + vcg::Point2 D=RandomPoint(SpaceSize); + D.Normalize(); + D*=maxdim; + P1=P0+D; +} + +void InitRandom(int num, + MyScalarType SpaceSize=100, + MyScalarType maxdim=1) +{ + AllocatedSeg.clear(); + AllocatedSeg.resize(num); + srand(clock()); + for (int i=0;i P0,P1; + RandomSeg(P0,P1,SpaceSize,maxdim); + AllocatedSeg[i]=MySegmentType(P0,P1); + //AllocatedSeg[i].deleted=false; + } + +} + + //**MARKER CLASSES**// class MyMarker { @@ -92,246 +115,213 @@ public: int mark; MyMarker(){mark=0;} - //MyMarker( MESH_TYPE *m) {SetMesh(m);} - void UnMarkAll(){mark++;} + + void UnMarkAll(){mark++;} bool IsMarked(MySegmentType* obj) - {return(obj->mark==mark);} + { + int markObj=obj->TMark(); + return(markObj==mark); + } void Mark(MySegmentType* obj) - {obj->mark=mark;} - /*void SetMesh(MESH_TYPE *_m) - {m=_m;}*/ + {obj->TMark()=mark;} + }; +//**GRID-RELATED STUFF**// +MyMarker mf; +vcg::GridStaticPtr2D Grid2D; -vcg::SpatialHashTable2D Hash2D; -std::vector Allocated; -MyMarker MyMark; - -void RandomSeg(vcg::Point2 &P0, - vcg::Point2 &P1, - MyScalarType SpaceSize=100, - MyScalarType maxdim=0.01) +//**QUERIES +MySegmentType * GetClosestSegment(MyCoordType & _p, + MyCoordType &_closestPt) { - MyScalarType dimAbs=SpaceSize*maxdim; - int dimension=RAND_MAX; + vcg::PointSegment2DEPFunctor PDistFunct; - int X=rand(); - int Y=rand(); - int dX=rand(); - int dY=rand(); - MyScalarType size=((MyScalarType)(rand()))/(MyScalarType)dimension; - - P0=vcg::Point2((MyScalarType)X/dimension,(MyScalarType)Y/dimension); - P0*=SpaceSize; - - vcg::Point2 D=vcg::Point2((MyScalarType)dX/dimension,(MyScalarType)dY/dimension); - D.Normalize(); - D*=size*dimAbs; - P1=P0+D; + MyScalarType _minDist; + MyScalarType _maxDist=std::numeric_limits::max(); + return (Grid2D.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt)); } -void InitRandom(int num, - MyScalarType SpaceSize=100, - MyScalarType maxdim=0.01) +void GetInBoxSegments(vcg::Box2 bbox,std::vector &result) { - Allocated.clear(); - Allocated.resize(num); - srand(clock()); - for (int i=0;i P0,P1; - RandomSeg(P0,P1,SpaceSize,maxdim); - Allocated[i]=MySegmentType(P0,P1); - Allocated[i].deleted=false; - } - + Grid2D.GetInBox(mf,bbox,result); } - -MyScalarType TestBox(int num_test=100000, - MyScalarType SpaceSize=100, - MyScalarType maxdim=0.02) +MySegmentType * DoRay(MyRayType & _r, + MyCoordType &_closestPt) { - //GetInBox(OBJMARKER & _marker,const Box2x _bbox,OBJPTRCONTAINER & _objectPtrs) - MyMark.UnMarkAll(); - //int t0=clock(); - int num=0; - for (int i=0;i P0,P1; - RandomSeg(P0,P1,SpaceSize,maxdim); - vcg::Box2 bbox; - bbox.Add(P0); - bbox.Add(P1); - std::vector result; - num+=Hash2D.GetInBox >(MyMark,bbox,result); - } - //int t1=clock(); - MyScalarType numd=(double)num/(double)num_test; - return numd; + MyRayType _ray1=_r; + _ray1.Normalize(); + typedef vcg::RaySegmentIntersectionFunctor SintFunct; + SintFunct rs; + MyScalarType _maxDist=std::numeric_limits::max(); + MyScalarType _t; + MySegmentType *seg=Grid2D.DoRay(rs,mf,_ray1,_maxDist,_t); + + if (seg==NULL)return NULL; + _closestPt=_ray1.Origin()+_ray1.Direction()*_t; + return seg; } -MyScalarType GetIntersectingSegments(MySegmentType *S, - std::vector &result, - bool subdivide=false) +//**BRUTE FORCE QUERIES +void GetInBoxSegmentsBruteF( vcg::Box2 bbox, + std::vector &result) { - ///get the bbox - result.clear(); - ///then get into the grid - std::vector inbox; - int num=0; - if (!subdivide) + for (int i=0;i::max(); + MySegmentType *ret=NULL; + for (int i=0;i test; + test=vcg::ClosestPoint(AllocatedSeg[i],_p); + MyScalarType currD=(test-_p).Norm(); + if (currD<_minDist) + { + _closestPt=test; + _minDist=currD; + ret=&AllocatedSeg[i]; + } + } + return ret; +} + +MySegmentType * DoRayBruteF(MyRayType & _r, + MyCoordType &_closestPt) +{ + MyScalarType _minDist=std::numeric_limits::max(); + MySegmentType *ret=NULL; + for (int i=0;i test; + bool inters=vcg::RaySegmentIntersection(_r,AllocatedSeg[i],test); + if (!inters)continue; + MyScalarType currD=(test-_r.Origin()).Norm(); + if (currD<_minDist) + { + _closestPt=test; + _minDist=currD; + ret=&AllocatedSeg[i]; + } + } + return ret; +} + + +void TestBox(int num_test=100000, + MyScalarType SpaceSize=100) +{ + int numWrong=0; + + for (int i=0;i P0=RandomPoint(SpaceSize); + vcg::Point2 P1=RandomPoint(SpaceSize); vcg::Box2 bbox; - S->GetBBox(bbox); - num=Hash2D.GetInBox >(MyMark,bbox,inbox); + bbox.Add(P0); + bbox.Add(P1); + std::vector result0; + GetInBoxSegments(bbox,result0); + + std::vector result1; + GetInBoxSegmentsBruteF(bbox,result1); + + std::sort(result0.begin(),result0.end()); + std::sort(result1.begin(),result1.end()); + + std::vector::iterator new_end=std::unique(result1.begin(),result1.end()); + int dist=distance(result1.begin(),new_end); + result1.resize(dist); + + if (result0.size()!=result1.size())numWrong++; + + for (int j = 0; j < result0.size(); j++) + if (result0[j] != result1[j]) + { + numWrong++; + } } - else - { - std::vector > bbox; - MyScalarType size_cell=Hash2D.cell_size; + printf("WRONG TESTS BBOX %d ON %d \n",numWrong,num_test); + fflush(stdout); +} - S->GetSubBBox(size_cell,bbox); - num=Hash2D.GetInBoxes >(MyMark,bbox,inbox); +void TestClosest(int num_test=100000, + MyScalarType SpaceSize=100) +{ + + int numWrong=0; + for (int i=0;i P0=RandomPoint(SpaceSize); + + vcg::Point2 closest0; + MySegmentType* result0=GetClosestSegment(P0,closest0); + + vcg::Point2 closest1; + MySegmentType* result1=GetClosesestSegmentBruteF(P0,closest1); + + + if (result0!=result1) + { + numWrong++; + printf("D0 %5.5f \n",(closest0-P0).Norm()); + printf("D1 %5.5f \n",(closest1-P0).Norm()); + fflush(stdout); + } } - ///then test intersection - for (int j=0;j p_inters; - if (vcg::SegmentSegmentIntersection(*S,*inbox[j],p_inters)) - result.push_back(inbox[j]); - } - return (((MyScalarType)num-result.size())/(MyScalarType)num); + printf("WRONG TESTS CLOSEST %d ON %d \n",numWrong,num_test); + fflush(stdout); } -MyScalarType GetCloseSegments(MySegmentType *S, - const MyScalarType &radius, - std::vector &result, - bool use_sub=false) +void TestRay(int num_test=100000, + MyScalarType SpaceSize=100) { - ///get the bbox - result.clear(); - std::vector inbox; - int num=0; - if (!use_sub) + int numWrong=0; + int NUll0=0; + int NUll1=0; + for (int i=0;i bbox; - S->GetBBox(bbox); - bbox.Offset(radius);//*1.02); - ///then get into the grid - num=Hash2D.GetInBox >(MyMark,bbox,inbox); + vcg::Point2 P0=RandomPoint(SpaceSize); + vcg::Point2 P1=RandomPoint(SpaceSize); + vcg::Point2 Orig=P0; + vcg::Point2 Dir=P1-P0; + Dir.Normalize(); + + MyRayType r(Orig,Dir); + + vcg::Point2 closest0; + MySegmentType* result0=DoRay(r,closest0); + + vcg::Point2 closest1; + MySegmentType* result1=DoRayBruteF(r,closest1); + + + if (result0!=result1) + { + numWrong++; +// printf("D0 %5.5f \n",(closest0-P0).Norm()); +// printf("D1 %5.5f \n",(closest1-P0).Norm()); +// fflush(stdout); + } + if (result0==NULL) NUll0++; + if (result1==NULL) NUll1++; } - else - { - std::vector > bbox; - MyScalarType size_cell=Hash2D.cell_size; - S->GetSubBBox(size_cell,bbox); - for (int i=0;i >(MyMark,bbox,inbox); - } - ///then test intersection - for (int j=0;j p_clos; - MyScalarType dist=vcg::Segment2DSegment2DDistance(*S,*inbox[j],p_clos); - if (dist result; - MyScalarType false_pos_t=GetIntersectingSegments(&Allocated[i],result,use_sub); - false_pos+=false_pos_t; - } - return (false_pos/(MyScalarType)num_test); -} - -MyScalarType TestClosest(unsigned int num_test=1000000, - MyScalarType radius=0.1, - bool use_sub=false) -{ - MyScalarType false_pos=0; - for (unsigned int i=0;iLength()*radius; - - ///get the segments closer than a radius - std::vector closer; - MyScalarType false_pos_t=GetCloseSegments(S,absRadius,closer,use_sub); - false_pos+=false_pos_t; - } - return (false_pos/(MyScalarType)num_test); -} - -int TestCorrectIntersect(int num_test=1000,bool use_sub=false) -{ - int num=0; - for (int i=0;i result0,result1; - for (int j=0;j p_inters; - if (vcg::SegmentSegmentIntersection(S0,*S1,p_inters)) - result0.push_back(S1); - /*num+=result0.size();*/ - } - GetIntersectingSegments(&Allocated[i],result1,use_sub); - ///then see if equal number - if (result1.size()==result0.size())num++; - } - return (num); -} - -int TestCorrectClosest(int num_test=1000, - MyScalarType radius=0.1, - bool use_sub=false) -{ - int num=0; - for (int i=0;i result0,result1; - MyScalarType absRadius=S0->Length()*radius; - for (int j=0;j p_clos; - MyScalarType dist=vcg::Segment2DSegment2DDistance(*S0,*S1,p_clos); - if (dist