/**************************************************************************** * 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;} typedef vcg::Point2 CoordType; 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())); } MySegmentType(){} MySegmentType(const MySegmentType &s1):vcg::Segment2(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; } MyScalarType GetIntersectingSegments(MySegmentType *S, std::vector &result, bool subdivide=false) { ///get the bbox result.clear(); ///then get into the grid std::vector inbox; int num=0; if (!subdivide) { vcg::Box2 bbox; S->GetBBox(bbox); num=Hash2D.GetInBox >(MyMark,bbox,inbox); } else { std::vector > bbox; MyScalarType size_cell=Hash2D.cell_size; S->GetSubBBox(size_cell,bbox); num=Hash2D.GetInBoxes >(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]); } return (((MyScalarType)num-result.size())/(MyScalarType)num); } MyScalarType GetCloseSegments(MySegmentType *S, const MyScalarType &radius, std::vector &result, bool use_sub=false) { ///get the bbox result.clear(); std::vector inbox; int num=0; if (!use_sub) { vcg::Box2 bbox; S->GetBBox(bbox); bbox.Offset(radius);//*1.02); ///then get into the grid num=Hash2D.GetInBox >(MyMark,bbox,inbox); } 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