diff --git a/apps/sample/hashing_2D/test_hash2D.cpp b/apps/sample/hashing_2D/test_hash2D.cpp new file mode 100644 index 00000000..ec575aac --- /dev/null +++ b/apps/sample/hashing_2D/test_hash2D.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +* 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 + +typedef double MyScalarType; + +class MySegmentType:public vcg::Segment2 +{ +public: + int mark; + bool deleted; + bool IsD(){return deleted;} + + MySegmentType(const vcg::Point2 &_P0, + const vcg::Point2 &_P1) + { + P0()=_P0; + P1()=_P1; + mark=0; + } + + void GetBBox(vcg::Box2 &BB2) + { + BB2.SetNull(); + BB2.Add(P0()); + BB2.Add(P1()); + } + + MySegmentType(){} + + MySegmentType(const MySegmentType &s1) + { + P0()=s1.P0(); + P1()=s1.P1(); + mark=s1.mark; + deleted=s1.deleted; + } +}; + +//**MARKER CLASSES**// +class MyMarker +{ + +public: + int mark; + + MyMarker(){mark=0;} + //MyMarker( MESH_TYPE *m) {SetMesh(m);} + void UnMarkAll(){mark++;} + + bool IsMarked(MySegmentType* obj) + {return(obj->mark==mark);} + + void Mark(MySegmentType* obj) + {obj->mark=mark;} + /*void SetMesh(MESH_TYPE *_m) + {m=_m;}*/ +}; + + +vcg::SpatialHashTable2D Hash2D; +std::vector Allocated; +MyMarker MyMark; + +void RandomSeg(vcg::Point2 &P0, + vcg::Point2 &P1, + MyScalarType SpaceSize=100, + MyScalarType maxdim=0.01) +{ + MyScalarType dimAbs=SpaceSize*maxdim; + int dimension=RAND_MAX; + + 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; +} + +void InitRandom(int num, + MyScalarType SpaceSize=100, + MyScalarType maxdim=0.01) +{ + 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; + } + +} + + +MyScalarType TestBox(int num_test=100000, + MyScalarType SpaceSize=100, + MyScalarType maxdim=0.02) +{ + //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; +} + +//void TestCorrectNess(int num_sample=1000, +// int num_test=1000, +// MyScalarType SpaceSize=100, +// MyScalarType radius=0.02) +//{ +// +//} + +void GetIntersectingSegments(MySegmentType *S, + std::vector &result) +{ + ///get the bbox + result.clear(); + vcg::Box2 bbox; + S->GetBBox(bbox); + ///then get into the grid + std::vector inbox; + int num=Hash2D.GetInBox >(MyMark,bbox,inbox); + ///then test intersection + for (int j=0;j p_inters; + if (vcg::SegmentSegmentIntersection(*S,*inbox[j],p_inters)) + result.push_back(inbox[j]); + } +} + +void GetCloseSegments(MySegmentType *S, + const MyScalarType &radius, + std::vector &result) +{ + ///get the bbox + result.clear(); + vcg::Box2 bbox; + S->GetBBox(bbox); + bbox.Offset(radius*1.02); + + ///then get into the grid + std::vector inbox; + int num=Hash2D.GetInBox >(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; + GetIntersectingSegments(&Allocated[i],result); + num_inters+=result.size(); + } + return ((MyScalarType)num_inters/(MyScalarType)num_test); +} + +MyScalarType TestClosest(int num_test=1000000, + MyScalarType radius=0.1) +{ + int num_found=0; + for (int i=0;iLength()*radius; + + ///get the segments closer than a radius + std::vector closer; + GetCloseSegments(S,absRadius,closer); + + num_found+=closer.size(); + } + return ((MyScalarType)num_found/(MyScalarType)num_test); +} + +int TestCorrectIntersect(int num_test=1000) +{ + 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); + ///then see if equal number + if (result1.size()==result0.size())num++; + } + return (num); +} + +int TestCorrectClosest(int num_test=1000, + MyScalarType radius=0.1) +{ + 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