J
jesper
In frustration I made this code using equal_range.
It does not behave in the way I expected however.
It finds the correct breakpoint in the set but finds it as
the first iterator. why?
I would like to do this with upper_bound instead.
//-----
#include <stdlib.h>
#include <math.h>
#include <set>
#include <iostream>
#include <algorithm>
#define random(A) (rand()%A)
class ObjectIn2DSpace
{
private:
double xpos;
double ypos;
static std::set<ObjectIn2DSpace*> AllObjects;
public:
double GetXPos(){return xpos;}
double GetYPos(){return ypos;}
ObjectIn2DSpace(){
xpos=random(100000)*(1/double(random(999)+1));
ypos=random(100000)*(1/double(random(999)+1));
AllObjects.insert(this);
}
~ObjectIn2DSpace(){
AllObjects.erase(this);
}
static void ClearAll()
{
while(!AllObjects.empty())
delete *(AllObjects.begin());
AllObjects.clear();
}
static std::set<ObjectIn2DSpace*>::iterator GetBegin(){return
AllObjects.begin();}
static std::set<ObjectIn2DSpace*>::iterator GetEnd(){return
AllObjects.end();}
static bool IsEnd(std::set<ObjectIn2DSpace*>::iterator it){return
it==AllObjects.end();}
};
std::set<ObjectIn2DSpace*> ObjectIn2DSpace::AllObjects;
class CompDist
{
ObjectIn2DSpace * CenterOn;
double MaxDistance;
public:
double DistanceTo(ObjectIn2DSpace* A)
{
double dx= CenterOn->GetXPos()-A->GetXPos();
double dy= CenterOn->GetYPos()-A->GetYPos();
return sqrt((dx*dx)+(dy*dy));
}
CompDist(){MaxDistance=-1.0;}
void SetCenterOn(ObjectIn2DSpace * In){CenterOn=In;}
ObjectIn2DSpace * GetCenterOn() {return CenterOn;}
void SetMaxDistance(double In){MaxDistance=In;}
bool operator()(ObjectIn2DSpace* A,ObjectIn2DSpace* B)
{
if(MaxDistance>=0)
{
double AD=std::min(DistanceTo(A),MaxDistance);
double BD=std::min(DistanceTo(B),MaxDistance);
if((AD==MaxDistance)||(BD==MaxDistance))
return false;
return true;
}
return DistanceTo(A)<DistanceTo(B);
}
};
template<class c>
void DumpDistances(c &Sorted,CompDist & Comp)
{
c::iterator it=Sorted.begin();
std::string s;
char itoabuf[15];
while(it!=Sorted.end())
{
std::cout<<itoa( int(Comp.DistanceTo(*it)),itoabuf,10);
std::cout<<"\r\n";
it++;
}
std::cout<<"\r\n";
}
int main() {
int n=10000;
srand(time(0));
while(n--)
new ObjectIn2DSpace();
CompDist Comp;
Comp.SetCenterOn(new ObjectIn2DSpace());
std::set<ObjectIn2DSpace*,CompDist>
Sorted(ObjectIn2DSpace::GetBegin(),ObjectIn2DSpace::GetEnd(),Comp);
double MaxDist=500.0;
Comp.SetMaxDistance(MaxDist);
std:
air<std::set<ObjectIn2DSpace*,CompDist>::iterator,
std::set<ObjectIn2DSpace*,CompDist>::iterator>
range=std::equal_range(Sorted.begin(),Sorted.end(),Comp.GetCenterOn(),Comp);
Comp.SetMaxDistance(-1);
std::set<ObjectIn2DSpace*,CompDist>
SortedMax(Sorted.begin(),range.first,Comp);
DumpDistances(SortedMax,Comp);
ObjectIn2DSpace::ClearAll();
}
It does not behave in the way I expected however.
It finds the correct breakpoint in the set but finds it as
the first iterator. why?
I would like to do this with upper_bound instead.
//-----
#include <stdlib.h>
#include <math.h>
#include <set>
#include <iostream>
#include <algorithm>
#define random(A) (rand()%A)
class ObjectIn2DSpace
{
private:
double xpos;
double ypos;
static std::set<ObjectIn2DSpace*> AllObjects;
public:
double GetXPos(){return xpos;}
double GetYPos(){return ypos;}
ObjectIn2DSpace(){
xpos=random(100000)*(1/double(random(999)+1));
ypos=random(100000)*(1/double(random(999)+1));
AllObjects.insert(this);
}
~ObjectIn2DSpace(){
AllObjects.erase(this);
}
static void ClearAll()
{
while(!AllObjects.empty())
delete *(AllObjects.begin());
AllObjects.clear();
}
static std::set<ObjectIn2DSpace*>::iterator GetBegin(){return
AllObjects.begin();}
static std::set<ObjectIn2DSpace*>::iterator GetEnd(){return
AllObjects.end();}
static bool IsEnd(std::set<ObjectIn2DSpace*>::iterator it){return
it==AllObjects.end();}
};
std::set<ObjectIn2DSpace*> ObjectIn2DSpace::AllObjects;
class CompDist
{
ObjectIn2DSpace * CenterOn;
double MaxDistance;
public:
double DistanceTo(ObjectIn2DSpace* A)
{
double dx= CenterOn->GetXPos()-A->GetXPos();
double dy= CenterOn->GetYPos()-A->GetYPos();
return sqrt((dx*dx)+(dy*dy));
}
CompDist(){MaxDistance=-1.0;}
void SetCenterOn(ObjectIn2DSpace * In){CenterOn=In;}
ObjectIn2DSpace * GetCenterOn() {return CenterOn;}
void SetMaxDistance(double In){MaxDistance=In;}
bool operator()(ObjectIn2DSpace* A,ObjectIn2DSpace* B)
{
if(MaxDistance>=0)
{
double AD=std::min(DistanceTo(A),MaxDistance);
double BD=std::min(DistanceTo(B),MaxDistance);
if((AD==MaxDistance)||(BD==MaxDistance))
return false;
return true;
}
return DistanceTo(A)<DistanceTo(B);
}
};
template<class c>
void DumpDistances(c &Sorted,CompDist & Comp)
{
c::iterator it=Sorted.begin();
std::string s;
char itoabuf[15];
while(it!=Sorted.end())
{
std::cout<<itoa( int(Comp.DistanceTo(*it)),itoabuf,10);
std::cout<<"\r\n";
it++;
}
std::cout<<"\r\n";
}
int main() {
int n=10000;
srand(time(0));
while(n--)
new ObjectIn2DSpace();
CompDist Comp;
Comp.SetCenterOn(new ObjectIn2DSpace());
std::set<ObjectIn2DSpace*,CompDist>
Sorted(ObjectIn2DSpace::GetBegin(),ObjectIn2DSpace::GetEnd(),Comp);
double MaxDist=500.0;
Comp.SetMaxDistance(MaxDist);
std:
std::set<ObjectIn2DSpace*,CompDist>::iterator>
range=std::equal_range(Sorted.begin(),Sorted.end(),Comp.GetCenterOn(),Comp);
Comp.SetMaxDistance(-1);
std::set<ObjectIn2DSpace*,CompDist>
SortedMax(Sorted.begin(),range.first,Comp);
DumpDistances(SortedMax,Comp);
ObjectIn2DSpace::ClearAll();
}