/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #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 IsD(){return false;} MySegmentType(const vcg::Point2 &_P0, const vcg::Point2 &_P1) { P0()=_P0; P1()=_P1; mark=0; } int &TMark(){return mark;} MySegmentType(){} MySegmentType(const MySegmentType &s1):vcg::Segment2(s1) { P0()=s1.P0(); P1()=s1.P1(); mark=s1.mark; } }; //**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 { public: int mark; MyMarker(){mark=0;} void UnMarkAll(){mark++;} bool IsMarked(MySegmentType* obj) { int markObj=obj->TMark(); return(markObj==mark); } void Mark(MySegmentType* obj) {obj->TMark()=mark;} }; //**GRID-RELATED STUFF**// MyMarker mf; vcg::GridStaticPtr2D Grid2D; //**QUERIES MySegmentType * GetClosestSegment(MyCoordType & _p, MyCoordType &_closestPt) { vcg::PointSegment2DEPFunctor PDistFunct; MyScalarType _minDist; MyScalarType _maxDist=std::numeric_limits::max(); return (Grid2D.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt)); } void GetInBoxSegments(vcg::Box2 bbox,std::vector &result) { Grid2D.GetInBox(mf,bbox,result); } MySegmentType * DoRay(MyRayType & _r, MyCoordType &_closestPt) { 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; } //**BRUTE FORCE QUERIES void GetInBoxSegmentsBruteF( vcg::Box2 bbox, std::vector &result) { vcg::Box2 ibbox; for (size_t i=0;i::max(); MySegmentType *ret=NULL; for (size_t 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 (size_t 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; 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 (size_t j = 0; j < result0.size(); j++) if (result0[j] != result1[j]) { numWrong++; } } printf("WRONG TESTS BBOX %d ON %d \n",numWrong,num_test); fflush(stdout); } 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); } } printf("WRONG TESTS CLOSEST %d ON %d \n",numWrong,num_test); fflush(stdout); } void TestRay(int num_test=100000, MyScalarType SpaceSize=100) { int numWrong=0; int NUll0=0; int NUll1=0; for (int i=0;i 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++; } printf("WRONG TESTS DORAY %d ON %d \n",numWrong,num_test); printf("NULL0 %d \n",NUll0); printf("NULL1 %d \n",NUll1); fflush(stdout); } int main( int argc, char **argv ) { (void) argc; (void) argv; int num_sample=20000; int t0=clock(); printf("** Random Initialization ** \n"); fflush(stdout); InitRandom(num_sample,100,0.3); int t1=clock(); ///Initialization performance printf("** Time elapsed for initialization of %d sample is %d\n \n",num_sample,t1-t0); Grid2D.Set(AllocatedSeg.begin(),AllocatedSeg.end()); fflush(stdout); //Box Query correctness TestBox(num_sample); TestClosest(num_sample); TestRay(num_sample); return 0; }