/**************************************************************************** * 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.Set(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