You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
9.0 KiB
C++

#include "StdAfx.h"
#include "ObjSortMgr.h"
#include "ObjContainer.h"
#include "Layer.h"
#include "GlobalFunction.h"
#include "ObjPoint.h"
#if 1//排序用函数
bool CompareDouble1(double val1,double val2)
{
return val1>val2;
}
bool CompareDouble2(double val1,double val2)
{
return val1<val2;
}
bool CompareObjX1(Sptr<CObjBase> &Obj1,Sptr<CObjBase> &Obj2)
{
Dbxy pt1 = Obj1->GetCenterPt();
Dbxy pt2 = Obj2->GetCenterPt();
return pt1.x>pt2.x;
}
bool CompareObjX2(Sptr<CObjBase> &Obj1,Sptr<CObjBase> &Obj2)
{
Dbxy pt1 = Obj1->GetCenterPt();
Dbxy pt2 = Obj2->GetCenterPt();
return pt1.x<pt2.x;
}
bool CompareObjY1(Sptr<CObjBase> &Obj1,Sptr<CObjBase> &Obj2)
{
Dbxy pt1 = Obj1->GetCenterPt();
Dbxy pt2 = Obj2->GetCenterPt();
return pt1.y>pt2.y;
}
bool CompareObjY2(Sptr<CObjBase> &Obj1,Sptr<CObjBase> &Obj2)
{
Dbxy pt1 = Obj1->GetCenterPt();
Dbxy pt2 = Obj2->GetCenterPt();
return pt1.y<pt2.y;
}
#endif
#define BUCKET_EPS 0.01 //桶的精度
CObjSortMgr::CObjSortMgr(void)
{
m_ScanDir = _DIR_L;
}
CObjSortMgr::~CObjSortMgr(void)
{
}
#if 1
//通过方向对obj 进行排序
void CObjSortMgr::SortObjByDir(DIRECTION dir)
{
m_ScanDir = dir;
//重置所有obj 的搜集状态
CObjContainer &LayerObjContainer = gLayer.GetObjContainer();
LayerObjContainer.ResetAllCollectedState();
//获取layer 的obj 容器
vector<Sptr<CObjBase>> &LayerObjVec = LayerObjContainer.GetObjVec();
//分离选择和非选择obj 到不同的容器
vector<Sptr<CObjBase>> SelObjVec;
vector<Sptr<CObjBase>> NotSelObjVec;
SeparateSelObj(LayerObjVec,SelObjVec,NotSelObjVec);
if(SelObjVec.empty())
return;
//对选择的obj 进行排序
SortObjVec(SelObjVec);
//将结果放回原来的容器
LayerObjVec.clear();
PushToObjVec(LayerObjVec,SelObjVec);
PushToObjVec(LayerObjVec,NotSelObjVec);
}
//分离选择和非选择obj 到不同的容器
void CObjSortMgr::SeparateSelObj(vector<Sptr<CObjBase>> &ObjVec,vector<Sptr<CObjBase>> &SelObjVec,vector<Sptr<CObjBase>> &NotSelObjVec)
{
vector<Sptr<CObjBase>>::iterator iter = ObjVec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = ObjVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter)->IsSelected())
SelObjVec.push_back(*iter);
else
NotSelObjVec.push_back(*iter);
}
}
//将结果放回原来的容器ObjVec2---->ObjVec1
void CObjSortMgr::PushToObjVec(vector<Sptr<CObjBase>> &ObjVec1,vector<Sptr<CObjBase>> &ObjVec2)
{
vector<Sptr<CObjBase>>::iterator iter = ObjVec2.begin();
vector<Sptr<CObjBase>>::iterator iter_end = ObjVec2.end();
for(;iter!=iter_end;iter++)
{
ObjVec1.push_back(*iter);
}
}
//是否横向扫描
bool CObjSortMgr::IsHorizontalScan()
{
if(m_ScanDir == _DIR_L || m_ScanDir == _DIR_R)
return true;
return false;
}
//是否为正向扫描
bool CObjSortMgr::IsForwardDirection()
{
if(m_ScanDir == _DIR_R || m_ScanDir == _DIR_D)
return true;
return false;
}
#endif
#if 1
//对容器中的obj 进行排序(桶排序思路)
void CObjSortMgr::SortObjVec(vector<Sptr<CObjBase>> &ObjVec)
{
vector<vector<Sptr<CObjBase>>> BucketVec;//桶序列(每个桶的第一个obj 表示桶的坐标)
//创建桶
CreatBucketVec(BucketVec,ObjVec);
//搜集桶的obj
CollectBucketObj(BucketVec,ObjVec);
//对每个桶进行排序
BucketSort(BucketVec);
//把桶的obj 倒回ObjVec
BucketToObjVec(BucketVec,ObjVec);
}
//创建桶
void CObjSortMgr::CreatBucketVec(vector<vector<Sptr<CObjBase>>> &BucketVec,vector<Sptr<CObjBase>> &ObjVec)
{
//创建桶基准坐标容器
vector<double> BucketBaseCoordVec;
CreatBucketBaseCoordVec(BucketBaseCoordVec,ObjVec);
//对桶基准坐标容器排序
if(IsForwardDirection())
sort(BucketBaseCoordVec.begin(),BucketBaseCoordVec.end(),CompareDouble1);
else
sort(BucketBaseCoordVec.begin(),BucketBaseCoordVec.end(),CompareDouble2);
//根据基准点创建桶
vector<double>::iterator iter = BucketBaseCoordVec.begin();
vector<double>::iterator iter_end = BucketBaseCoordVec.end();
for(;iter!=iter_end;iter++)
{
//每个桶的第一个obj 为基准
CObjPoint *p = new CObjPoint;
p->SetPt(Dbxy((*iter),(*iter)));//x y都设置为一样,这里就不用区分方向
//保存到智能指针
Sptr<CObjBase> sPtr(p);
vector<Sptr<CObjBase>> Bucket;//创建一个桶
Bucket.push_back(sPtr);
BucketVec.push_back(Bucket);
}
}
//创建桶基准坐标容器(区分横向和竖向)
void CObjSortMgr::CreatBucketBaseCoordVec(vector<double> &BucketBaseCoordVec,vector<Sptr<CObjBase>> &ObjVec)
{
vector<Sptr<CObjBase>>::iterator iter = ObjVec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = ObjVec.end();
for(;iter!=iter_end;iter++)
{
Dbxy pt = (*iter)->GetCenterPt();//obj 中心点
double Val = IsHorizontalScan()?pt.x:pt.y;
bool bFlg = true;//是否要加入
int size = BucketBaseCoordVec.size();
for(int k=0;k<size;k++)
{
if(IsTwoDbEqual(Val,BucketBaseCoordVec[k],BUCKET_EPS))
{
bFlg = false;
break;
}
}
if(bFlg)//只有新的val 才加入
{
BucketBaseCoordVec.push_back(Val);
}
}
}
//搜集桶的obj
void CObjSortMgr::CollectBucketObj(vector<vector<Sptr<CObjBase>>> &BucketVec,vector<Sptr<CObjBase>> &ObjVec)
{
vector<vector<Sptr<CObjBase>>>::iterator iter = BucketVec.begin();
vector<vector<Sptr<CObjBase>>>::iterator iter_end = BucketVec.end();
for(;iter!=iter_end;iter++)
{
vector<Sptr<CObjBase>> &Bucket = (*iter);
Dbxy BasePt = Bucket[0]->GetCenterPt();
double BaseVal = IsHorizontalScan()?BasePt.x:BasePt.y;//基准值
Bucket.clear();//清除用作基准的obj
vector<Sptr<CObjBase>>::iterator ObjIter = ObjVec.begin();
vector<Sptr<CObjBase>>::iterator ObjIter_end = ObjVec.end();
for(;ObjIter!=ObjIter_end;ObjIter++)
{
Sptr<CObjBase> &Obj = (*ObjIter);
if(!Obj->IsbCollected())//避免重复收集
{
Dbxy ObjPt = Obj->GetCenterPt();
double ObjVal = IsHorizontalScan()?ObjPt.x:ObjPt.y;//比较值
if(IsTwoDbEqual(BaseVal,ObjVal,BUCKET_EPS))//发现属于桶的obj
{
Bucket.push_back(Obj);
Obj->SetbCollected(true);//设置收集状态
}
}
}
}
}
//对每个桶进行排序
void CObjSortMgr::BucketSort(vector<vector<Sptr<CObjBase>>> &BucketVec)
{
bool bDir = true;//用于生成S 形数据
vector<vector<Sptr<CObjBase>>>::iterator iter = BucketVec.begin();
vector<vector<Sptr<CObjBase>>>::iterator iter_end = BucketVec.end();
for(;iter!=iter_end;iter++)
{
vector<Sptr<CObjBase>> &Bucket = (*iter);
if(IsHorizontalScan())//横向扫描按Y 方向排序
{
if(bDir)
sort(Bucket.begin(),Bucket.end(),CompareObjY1);
else
sort(Bucket.begin(),Bucket.end(),CompareObjY2);
}
else//竖向扫描按X 方向排序
{
if(bDir)
sort(Bucket.begin(),Bucket.end(),CompareObjX1);
else
sort(Bucket.begin(),Bucket.end(),CompareObjX2);
}
bDir =!bDir;//反向
}
}
//把桶的obj 倒回ObjVec
void CObjSortMgr::BucketToObjVec(vector<vector<Sptr<CObjBase>>> &BucketVec,vector<Sptr<CObjBase>> &ObjVec)
{
ObjVec.clear();
vector<vector<Sptr<CObjBase>>>::iterator iter = BucketVec.begin();
vector<vector<Sptr<CObjBase>>>::iterator iter_end = BucketVec.end();
for(;iter!=iter_end;iter++)
{
vector<Sptr<CObjBase>> &Bucket = (*iter);
vector<Sptr<CObjBase>>::iterator BucketIter = Bucket.begin();
vector<Sptr<CObjBase>>::iterator BuckeIter_end = Bucket.end();
for(;BucketIter!=BuckeIter_end;BucketIter++)
{
ObjVec.push_back(*BucketIter);
}
}
}
#endif
#if 0//周杰的排序算法
void CObjSortMgr::PlineSort(vector<vector<Dbxy>> &LineVec)
{
double gl;
double Min_gl=0;
double sum1,sum2;
int n=0;
for (vector<vector<Dbxy>>::size_type i=0;i!=(LineVec.size()-1);++i)
{
Dbxy ed1=LineVec[i].back();
for (vector<vector<Dbxy>>::size_type j=i+1;j!=LineVec.size();++j)
{
Dbxy ed2=LineVec[j].back();
Dbxy beg=LineVec[j].front();
sum1=sqrt((ed1.x-beg.x)*(ed1.x-beg.x)+(ed1.y-beg.y)*(ed1.y-beg.y));
sum2=sqrt((ed1.x-ed2.x)*(ed1.x-ed2.x)+(ed1.y-ed2.y)*(ed1.y-ed2.y));
if (sum2<sum1)
{
reverse(LineVec[j].begin(),LineVec[j].end());
gl=sum2;
}
else
{
gl=sum1;
}
if (j==i+1)
{
Min_gl=gl;
n=j;
}
if (gl<Min_gl)
{
Min_gl=gl;
n=j;
}
}
swap(LineVec[i+1],LineVec[n]);
}
}
#endif