add vcglib
This commit is contained in:
1 parent
6f6c0c8eb7
commit
af8100f851
1537 files changed
+634197
No files matched your search
@@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(space_index_2d)
|
||||
|
||||
if (VCG_HEADER_ONLY)
|
||||
set(SOURCES
|
||||
space_index_2d.cpp)
|
||||
endif()
|
||||
|
||||
add_executable(space_index_2d
|
||||
${SOURCES})
|
||||
|
||||
target_link_libraries(
|
||||
space_index_2d
|
||||
PUBLIC
|
||||
vcglib
|
||||
)
|
||||
@@ -0,0 +1,350 @@
|
||||
/****************************************************************************
|
||||
* 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 <stdio.h>
|
||||
#include <time.h>
|
||||
#include <vcg/space/distance2.h>
|
||||
#include <vcg/space/segment2.h>
|
||||
#include <vcg/space/index/grid_static_ptr2d.h>
|
||||
#include <vcg/space/index/grid_closest2d.h>
|
||||
#include <vcg/space/intersection2.h>
|
||||
|
||||
typedef double MyScalarType;
|
||||
typedef vcg::Point2<MyScalarType> MyCoordType;
|
||||
typedef vcg::Ray2<MyScalarType> MyRayType;
|
||||
|
||||
//**BASIC SEGMENT CLASS
|
||||
class MySegmentType:public vcg::Segment2<MyScalarType>
|
||||
{
|
||||
public:
|
||||
int mark;
|
||||
bool IsD(){return false;}
|
||||
|
||||
MySegmentType(const vcg::Point2<MyScalarType> &_P0,
|
||||
const vcg::Point2<MyScalarType> &_P1)
|
||||
{
|
||||
P0()=_P0;
|
||||
P1()=_P1;
|
||||
mark=0;
|
||||
}
|
||||
|
||||
int &TMark(){return mark;}
|
||||
|
||||
MySegmentType(){}
|
||||
|
||||
MySegmentType(const MySegmentType &s1):vcg::Segment2<MyScalarType>(s1)
|
||||
{
|
||||
P0()=s1.P0();
|
||||
P1()=s1.P1();
|
||||
mark=s1.mark;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//**ALLOCATED SEGMENTS**//
|
||||
std::vector<MySegmentType> AllocatedSeg;
|
||||
|
||||
//**GENERATION OF RANDOM SEGMENTS
|
||||
|
||||
vcg::Point2<MyScalarType> RandomPoint(MyScalarType SpaceSize=100)
|
||||
{
|
||||
int dimension=RAND_MAX;
|
||||
int X=rand();
|
||||
int Y=rand();
|
||||
vcg::Point2<MyScalarType> P0=vcg::Point2<MyScalarType>((MyScalarType)X/dimension,(MyScalarType)Y/dimension);
|
||||
P0*=SpaceSize;
|
||||
return P0;
|
||||
}
|
||||
|
||||
|
||||
void RandomSeg(vcg::Point2<MyScalarType> &P0,
|
||||
vcg::Point2<MyScalarType> &P1,
|
||||
MyScalarType SpaceSize=100,
|
||||
MyScalarType maxdim=1)
|
||||
{
|
||||
|
||||
P0=RandomPoint(SpaceSize);
|
||||
vcg::Point2<MyScalarType> 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<num;i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> 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<MySegmentType,MyScalarType> Grid2D;
|
||||
|
||||
//**QUERIES
|
||||
MySegmentType * GetClosestSegment(MyCoordType & _p,
|
||||
MyCoordType &_closestPt)
|
||||
{
|
||||
vcg::PointSegment2DEPFunctor<MyScalarType> PDistFunct;
|
||||
|
||||
MyScalarType _minDist;
|
||||
MyScalarType _maxDist=std::numeric_limits<MyScalarType>::max();
|
||||
return (Grid2D.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
|
||||
}
|
||||
|
||||
void GetInBoxSegments(vcg::Box2<MyScalarType> bbox,std::vector<MySegmentType*> &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<MyScalarType>::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<MyScalarType> bbox,
|
||||
std::vector<MySegmentType*> &result)
|
||||
{
|
||||
vcg::Box2<MyScalarType> ibbox;
|
||||
for (size_t i=0;i<AllocatedSeg.size();i++)
|
||||
{
|
||||
AllocatedSeg[i].GetBBox(ibbox);
|
||||
if (!ibbox.Collide(bbox)) continue;
|
||||
result.push_back(&AllocatedSeg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
MySegmentType* GetClosesestSegmentBruteF(MyCoordType & _p,
|
||||
MyCoordType &_closestPt)
|
||||
{
|
||||
MyScalarType _minDist=std::numeric_limits<MyScalarType>::max();
|
||||
MySegmentType *ret=NULL;
|
||||
for (size_t i=0;i<AllocatedSeg.size();i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> 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<MyScalarType>::max();
|
||||
MySegmentType *ret=NULL;
|
||||
for (size_t i=0;i<AllocatedSeg.size();i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> 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<num_test;i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
|
||||
vcg::Point2<MyScalarType> P1=RandomPoint(SpaceSize);
|
||||
vcg::Box2<MyScalarType> bbox;
|
||||
bbox.Add(P0);
|
||||
bbox.Add(P1);
|
||||
std::vector<MySegmentType*> result0;
|
||||
GetInBoxSegments(bbox,result0);
|
||||
|
||||
std::vector<MySegmentType*> result1;
|
||||
GetInBoxSegmentsBruteF(bbox,result1);
|
||||
|
||||
std::sort(result0.begin(),result0.end());
|
||||
std::sort(result1.begin(),result1.end());
|
||||
|
||||
std::vector<MySegmentType*>::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<num_test;i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
|
||||
|
||||
vcg::Point2<MyScalarType> closest0;
|
||||
MySegmentType* result0=GetClosestSegment(P0,closest0);
|
||||
|
||||
vcg::Point2<MyScalarType> 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<num_test;i++)
|
||||
{
|
||||
vcg::Point2<MyScalarType> P0=RandomPoint(SpaceSize);
|
||||
vcg::Point2<MyScalarType> P1=RandomPoint(SpaceSize);
|
||||
vcg::Point2<MyScalarType> Orig=P0;
|
||||
vcg::Point2<MyScalarType> Dir=P1-P0;
|
||||
Dir.Normalize();
|
||||
|
||||
MyRayType r(Orig,Dir);
|
||||
|
||||
vcg::Point2<MyScalarType> closest0;
|
||||
MySegmentType* result0=DoRay(r,closest0);
|
||||
|
||||
vcg::Point2<MyScalarType> 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;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
include(../common.pri)
|
||||
TARGET = space_index_2d
|
||||
HEADERS += ../../../vcg/space/index/grid_static_ptr2d.h\
|
||||
../../../vcg/space/index/closest2d.h\
|
||||
../../../vcg/space/index/space_iterators2d.h\
|
||||
../../../vcg/space/index/grid_closest2d.h
|
||||
SOURCES += space_index_2d.cpp
|
||||
Reference in new issue
Block a user