added support for primitive subdivision into cells
This commit is contained in:
parent
143169d28c
commit
7bb3900d3b
|
@ -33,32 +33,54 @@ class MySegmentType:public vcg::Segment2<MyScalarType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int mark;
|
int mark;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
bool IsD(){return deleted;}
|
bool IsD(){return deleted;}
|
||||||
|
typedef vcg::Point2<ScalarType> CoordType;
|
||||||
|
|
||||||
MySegmentType(const vcg::Point2<MyScalarType> &_P0,
|
MySegmentType(const vcg::Point2<MyScalarType> &_P0,
|
||||||
const vcg::Point2<MyScalarType> &_P1)
|
const vcg::Point2<MyScalarType> &_P1)
|
||||||
{
|
{
|
||||||
P0()=_P0;
|
P0()=_P0;
|
||||||
P1()=_P1;
|
P1()=_P1;
|
||||||
mark=0;
|
mark=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetBBox(vcg::Box2<ScalarType> &BB2)
|
void GetBBox(vcg::Box2<ScalarType> &BB2)
|
||||||
{
|
{
|
||||||
//BB2.SetNull();
|
//BB2.SetNull();
|
||||||
BB2.Set(P0());
|
BB2.Set(P0());
|
||||||
BB2.Add(P1());
|
BB2.Add(P1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetSubBBox(const ScalarType &step_size,
|
||||||
|
std::vector<vcg::Box2<ScalarType> > &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<steps-1;i++)
|
||||||
|
{
|
||||||
|
currP1=currP0+dir*step_size;
|
||||||
|
RasterBox[i]=(vcg::Box2<ScalarType>(currP0,currP1));
|
||||||
|
currP0=currP1;
|
||||||
|
}
|
||||||
|
RasterBox[steps-1]=(vcg::Box2<ScalarType>(currP0,P1()));
|
||||||
|
}
|
||||||
|
|
||||||
MySegmentType(){}
|
MySegmentType(){}
|
||||||
|
|
||||||
MySegmentType(const MySegmentType &s1)
|
MySegmentType(const MySegmentType &s1):vcg::Segment2<MyScalarType>(s1)
|
||||||
{
|
{
|
||||||
P0()=s1.P0();
|
P0()=s1.P0();
|
||||||
P1()=s1.P1();
|
P1()=s1.P1();
|
||||||
mark=s1.mark;
|
mark=s1.mark;
|
||||||
deleted=s1.deleted;
|
deleted=s1.deleted;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,7 +156,7 @@ MyScalarType TestBox(int num_test=100000,
|
||||||
{
|
{
|
||||||
//GetInBox(OBJMARKER & _marker,const Box2x _bbox,OBJPTRCONTAINER & _objectPtrs)
|
//GetInBox(OBJMARKER & _marker,const Box2x _bbox,OBJPTRCONTAINER & _objectPtrs)
|
||||||
MyMark.UnMarkAll();
|
MyMark.UnMarkAll();
|
||||||
int t0=clock();
|
//int t0=clock();
|
||||||
int num=0;
|
int num=0;
|
||||||
for (int i=0;i<num_test;i++)
|
for (int i=0;i<num_test;i++)
|
||||||
{
|
{
|
||||||
|
@ -146,80 +168,103 @@ MyScalarType TestBox(int num_test=100000,
|
||||||
std::vector<MySegmentType*> result;
|
std::vector<MySegmentType*> result;
|
||||||
num+=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,result);
|
num+=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,result);
|
||||||
}
|
}
|
||||||
int t1=clock();
|
//int t1=clock();
|
||||||
MyScalarType numd=(double)num/(double)num_test;
|
MyScalarType numd=(double)num/(double)num_test;
|
||||||
return numd;
|
return numd;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void TestCorrectNess(int num_sample=1000,
|
MyScalarType GetIntersectingSegments(MySegmentType *S,
|
||||||
// int num_test=1000,
|
std::vector<MySegmentType*> &result,
|
||||||
// MyScalarType SpaceSize=100,
|
bool subdivide=false)
|
||||||
// MyScalarType radius=0.02)
|
|
||||||
//{
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
void GetIntersectingSegments(MySegmentType *S,
|
|
||||||
std::vector<MySegmentType*> &result)
|
|
||||||
{
|
{
|
||||||
///get the bbox
|
///get the bbox
|
||||||
result.clear();
|
result.clear();
|
||||||
vcg::Box2<MyScalarType> bbox;
|
///then get into the grid
|
||||||
S->GetBBox(bbox);
|
std::vector<MySegmentType*> inbox;
|
||||||
///then get into the grid
|
int num=0;
|
||||||
std::vector<MySegmentType*> inbox;
|
if (!subdivide)
|
||||||
int num=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
{
|
||||||
|
vcg::Box2<MyScalarType> bbox;
|
||||||
|
S->GetBBox(bbox);
|
||||||
|
num=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<vcg::Box2<MyScalarType> > bbox;
|
||||||
|
MyScalarType size_cell=Hash2D.cell_size;
|
||||||
|
|
||||||
|
S->GetSubBBox(size_cell,bbox);
|
||||||
|
num=Hash2D.GetInBoxes<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
||||||
|
}
|
||||||
///then test intersection
|
///then test intersection
|
||||||
for (int j=0;j<num;j++)
|
for (int j=0;j<num;j++)
|
||||||
{
|
{
|
||||||
if (inbox[j]==S)continue;
|
if (inbox[j]==S)continue;
|
||||||
vcg::Point2<MyScalarType> p_inters;
|
vcg::Point2<MyScalarType> p_inters;
|
||||||
if (vcg::SegmentSegmentIntersection<MyScalarType>(*S,*inbox[j],p_inters))
|
if (vcg::SegmentSegmentIntersection<MyScalarType>(*S,*inbox[j],p_inters))
|
||||||
result.push_back(inbox[j]);
|
result.push_back(inbox[j]);
|
||||||
}
|
}
|
||||||
|
return (((MyScalarType)num-result.size())/(MyScalarType)num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetCloseSegments(MySegmentType *S,
|
MyScalarType GetCloseSegments(MySegmentType *S,
|
||||||
const MyScalarType &radius,
|
const MyScalarType &radius,
|
||||||
std::vector<MySegmentType*> &result)
|
std::vector<MySegmentType*> &result,
|
||||||
|
bool use_sub=false)
|
||||||
{
|
{
|
||||||
///get the bbox
|
///get the bbox
|
||||||
result.clear();
|
result.clear();
|
||||||
vcg::Box2<MyScalarType> bbox;
|
std::vector<MySegmentType*> inbox;
|
||||||
S->GetBBox(bbox);
|
int num=0;
|
||||||
bbox.Offset(radius);//*1.02);
|
if (!use_sub)
|
||||||
|
{
|
||||||
///then get into the grid
|
vcg::Box2<MyScalarType> bbox;
|
||||||
std::vector<MySegmentType*> inbox;
|
S->GetBBox(bbox);
|
||||||
int num=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
bbox.Offset(radius);//*1.02);
|
||||||
|
///then get into the grid
|
||||||
|
num=Hash2D.GetInBox<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<vcg::Box2<MyScalarType> > bbox;
|
||||||
|
MyScalarType size_cell=Hash2D.cell_size;
|
||||||
|
S->GetSubBBox(size_cell,bbox);
|
||||||
|
for (int i=0;i<bbox.size();i++)
|
||||||
|
bbox[i].Offset(radius);//*1.02);
|
||||||
|
///then get into the grid
|
||||||
|
num=Hash2D.GetInBoxes<MyMarker,std::vector<MySegmentType*> >(MyMark,bbox,inbox);
|
||||||
|
}
|
||||||
///then test intersection
|
///then test intersection
|
||||||
for (int j=0;j<num;j++)
|
for (int j=0;j<num;j++)
|
||||||
{
|
{
|
||||||
if (inbox[j]==S)continue;
|
if (inbox[j]==S)continue;
|
||||||
vcg::Point2<MyScalarType> p_clos;
|
vcg::Point2<MyScalarType> p_clos;
|
||||||
MyScalarType dist=vcg::Segment2DSegment2DDistance<MyScalarType>(*S,*inbox[j],p_clos);
|
MyScalarType dist=vcg::Segment2DSegment2DDistance<MyScalarType>(*S,*inbox[j],p_clos);
|
||||||
if (dist<radius) result.push_back(inbox[j]);
|
if (dist<radius)
|
||||||
|
result.push_back(inbox[j]);
|
||||||
}
|
}
|
||||||
|
return (((MyScalarType)num-result.size())/(MyScalarType)num);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyScalarType TestIntersection(int num_test=1000000)
|
MyScalarType TestIntersection(unsigned int num_test=1000000,bool use_sub=false)
|
||||||
{
|
{
|
||||||
int num_inters=0;
|
MyScalarType false_pos=0;
|
||||||
for (int i=0;i<num_test;i++)
|
for (unsigned int i=0;i<num_test;i++)
|
||||||
{
|
{
|
||||||
assert(i<Allocated.size());
|
assert(i<Allocated.size());
|
||||||
std::vector<MySegmentType*> result;
|
std::vector<MySegmentType*> result;
|
||||||
GetIntersectingSegments(&Allocated[i],result);
|
MyScalarType false_pos_t=GetIntersectingSegments(&Allocated[i],result,use_sub);
|
||||||
num_inters+=result.size();
|
false_pos+=false_pos_t;
|
||||||
}
|
}
|
||||||
return ((MyScalarType)num_inters/(MyScalarType)num_test);
|
return (false_pos/(MyScalarType)num_test);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyScalarType TestClosest(int num_test=1000000,
|
MyScalarType TestClosest(unsigned int num_test=1000000,
|
||||||
MyScalarType radius=0.1)
|
MyScalarType radius=0.1,
|
||||||
|
bool use_sub=false)
|
||||||
{
|
{
|
||||||
int num_found=0;
|
MyScalarType false_pos=0;
|
||||||
for (int i=0;i<num_test;i++)
|
for (unsigned int i=0;i<num_test;i++)
|
||||||
{
|
{
|
||||||
assert(i<Allocated.size());
|
assert(i<Allocated.size());
|
||||||
|
|
||||||
|
@ -230,14 +275,13 @@ MyScalarType TestClosest(int num_test=1000000,
|
||||||
|
|
||||||
///get the segments closer than a radius
|
///get the segments closer than a radius
|
||||||
std::vector<MySegmentType*> closer;
|
std::vector<MySegmentType*> closer;
|
||||||
GetCloseSegments(S,absRadius,closer);
|
MyScalarType false_pos_t=GetCloseSegments(S,absRadius,closer,use_sub);
|
||||||
|
false_pos+=false_pos_t;
|
||||||
num_found+=closer.size();
|
|
||||||
}
|
}
|
||||||
return ((MyScalarType)num_found/(MyScalarType)num_test);
|
return (false_pos/(MyScalarType)num_test);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestCorrectIntersect(int num_test=1000)
|
int TestCorrectIntersect(int num_test=1000,bool use_sub=false)
|
||||||
{
|
{
|
||||||
int num=0;
|
int num=0;
|
||||||
for (int i=0;i<num_test;i++)
|
for (int i=0;i<num_test;i++)
|
||||||
|
@ -253,7 +297,7 @@ int TestCorrectIntersect(int num_test=1000)
|
||||||
result0.push_back(S1);
|
result0.push_back(S1);
|
||||||
/*num+=result0.size();*/
|
/*num+=result0.size();*/
|
||||||
}
|
}
|
||||||
GetIntersectingSegments(&Allocated[i],result1);
|
GetIntersectingSegments(&Allocated[i],result1,use_sub);
|
||||||
///then see if equal number
|
///then see if equal number
|
||||||
if (result1.size()==result0.size())num++;
|
if (result1.size()==result0.size())num++;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +305,8 @@ int TestCorrectIntersect(int num_test=1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestCorrectClosest(int num_test=1000,
|
int TestCorrectClosest(int num_test=1000,
|
||||||
MyScalarType radius=0.1)
|
MyScalarType radius=0.1,
|
||||||
|
bool use_sub=false)
|
||||||
{
|
{
|
||||||
int num=0;
|
int num=0;
|
||||||
for (int i=0;i<num_test;i++)
|
for (int i=0;i<num_test;i++)
|
||||||
|
@ -279,7 +324,7 @@ int TestCorrectClosest(int num_test=1000,
|
||||||
result0.push_back(S1);
|
result0.push_back(S1);
|
||||||
/*num+=result0.size();*/
|
/*num+=result0.size();*/
|
||||||
}
|
}
|
||||||
GetCloseSegments(S0,absRadius,result1);
|
GetCloseSegments(S0,absRadius,result1,use_sub);
|
||||||
///then see if equal number
|
///then see if equal number
|
||||||
if (result1.size()==result0.size())num++;
|
if (result1.size()==result0.size())num++;
|
||||||
}
|
}
|
||||||
|
@ -289,14 +334,17 @@ int TestCorrectClosest(int num_test=1000,
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
int num_sample=100000;
|
bool use_sub=true;
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
int num_sample=20000;
|
||||||
int t0=clock();
|
int t0=clock();
|
||||||
InitRandom(100000);
|
InitRandom(num_sample,100,0.3);
|
||||||
int t1=clock();
|
int t1=clock();
|
||||||
|
|
||||||
///Initialization performance
|
///Initialization performance
|
||||||
printf("** Time elapsed for initialization of %d sample is %d\n \n",num_sample,t1-t0);
|
printf("** Time elapsed for initialization of %d sample is %d\n \n",num_sample,t1-t0);
|
||||||
Hash2D.Set(Allocated.begin(),Allocated.end());
|
Hash2D.Set(Allocated.begin(),Allocated.end(),use_sub);
|
||||||
|
|
||||||
///Box Query performance
|
///Box Query performance
|
||||||
t0=clock();
|
t0=clock();
|
||||||
|
@ -307,27 +355,27 @@ int main( int argc, char **argv )
|
||||||
|
|
||||||
///Intersecting segment performance
|
///Intersecting segment performance
|
||||||
t0=clock();
|
t0=clock();
|
||||||
MyScalarType avg_int=TestIntersection(num_sample);
|
MyScalarType perc_int=TestIntersection(num_sample,use_sub);
|
||||||
t1=clock();
|
t1=clock();
|
||||||
printf("** Time elapsed for %d INTERSECTION queries is %d\n, average found %5.5f \n \n",num_sample,t1-t0,avg_int);
|
printf("** Time elapsed for %d INTERSECTION queries is %d\n, false positive perc found %5.5f \n \n",num_sample,t1-t0,perc_int);
|
||||||
|
|
||||||
///closest test
|
///closest test
|
||||||
t0=clock();
|
t0=clock();
|
||||||
MyScalarType avg_clos=TestClosest(num_sample);
|
MyScalarType perc_clos=TestClosest(num_sample,0.1,use_sub);
|
||||||
t1=clock();
|
t1=clock();
|
||||||
printf("** Time elapsed for %d CLOSEST queries is %d\n, average found %5.5f \n \n",num_sample,t1-t0,avg_clos);
|
printf("** Time elapsed for %d CLOSEST queries is %d\n, false positive perc found %5.5f \n \n",num_sample,t1-t0,perc_clos);
|
||||||
|
|
||||||
///reinitialize structure
|
///reinitialize structure
|
||||||
MyMark.mark=0;
|
MyMark.mark=0;
|
||||||
Hash2D.Clear();
|
Hash2D.Clear();
|
||||||
int n_test=1000;
|
int n_test=1000;
|
||||||
InitRandom(n_test,100,0.1);
|
InitRandom(n_test,100,0.1);
|
||||||
Hash2D.Set(Allocated.begin(),Allocated.end());
|
Hash2D.Set(Allocated.begin(),Allocated.end(),use_sub);
|
||||||
|
|
||||||
int tested_int=TestCorrectIntersect(n_test);
|
int tested_int=TestCorrectIntersect(n_test,use_sub);
|
||||||
printf("** Correct Intersect on %d test are %d \n",n_test,tested_int);
|
printf("** Correct Intersect on %d test are %d \n",n_test,tested_int);
|
||||||
|
|
||||||
int tested_clos=TestCorrectClosest(n_test);
|
int tested_clos=TestCorrectClosest(n_test,0.1,use_sub);
|
||||||
printf("** Correct Closest on %d test are %d \n",n_test,tested_clos);
|
printf("** Correct Closest on %d test are %d \n",n_test,tested_clos);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue