840 lines
22 KiB
C++
840 lines
22 KiB
C++
|
#include "Stdafx.h"
|
|||
|
#include "ClosedFinder.h"
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
ClosedFinder::ClosedFinder(void)
|
|||
|
{
|
|||
|
tCurMaxSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
ClosedFinder::~ClosedFinder(void)
|
|||
|
{
|
|||
|
for (std::map<Point_Key, sPoint*>::iterator pit =mPointsSrc.begin();
|
|||
|
pit != mPointsSrc.end();++pit)
|
|||
|
{
|
|||
|
if(pit->second != NULL)
|
|||
|
{
|
|||
|
delete pit->second;
|
|||
|
pit->second = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
for (std::map<Arc_Key , sArc* >::iterator pit =mArcsSrc.begin();
|
|||
|
pit != mArcsSrc.end();++pit)
|
|||
|
{
|
|||
|
if(pit->second != NULL)
|
|||
|
{
|
|||
|
delete pit->second;
|
|||
|
pit->second = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
mPointsSrc.clear();
|
|||
|
mArcsSrc.clear();
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::getArcHalfEdgeBeginEnd(const std::list<sArcHalfEdge>& lstEdge, const sPoint* & ptFist , const sPoint* & ptEnd)
|
|||
|
{
|
|||
|
if (!lstEdge.empty())
|
|||
|
{
|
|||
|
//sArcHalfEdge::ArcHalfEdge_const_iterator itFirst(&(*lstEdge.begin()));
|
|||
|
//sArcHalfEdge::ArcHalfEdge_const_iterator itEnd(&(*lstEdge.rbegin()));
|
|||
|
|
|||
|
////ptFist = itFirst.First();
|
|||
|
////ptEnd = itEnd.GetEnd();
|
|||
|
|
|||
|
if(lstEdge.size() == 1)
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itFirst(&(*lstEdge.begin()));
|
|||
|
ptFist = itFirst.First();
|
|||
|
ptEnd = itFirst.GetEnd();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
std::list<sArcHalfEdge>::const_iterator iter = lstEdge.begin();
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itFirst(&(*iter++));
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itEnd(&(*iter));
|
|||
|
const sPoint* sp1 = itFirst.First();
|
|||
|
const sPoint* ep1 = itFirst.GetEnd();
|
|||
|
const sPoint* sp2 = itEnd.First();
|
|||
|
const sPoint* ep2 = itEnd.GetEnd();
|
|||
|
|
|||
|
if(sp1->m_Id == sp2->m_Id || sp1->m_Id == ep2->m_Id)
|
|||
|
{
|
|||
|
ptFist = ep1;
|
|||
|
ptEnd = sp1;
|
|||
|
}
|
|||
|
else if(ep1->m_Id == sp2->m_Id || ep1->m_Id == ep2->m_Id)
|
|||
|
{
|
|||
|
ptFist = sp1;
|
|||
|
ptEnd = ep1;
|
|||
|
}
|
|||
|
|
|||
|
for(;iter != lstEdge.end(); iter++)
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator it(&(*iter));
|
|||
|
const sPoint* sp = it.First();
|
|||
|
const sPoint* ep = it.GetEnd();
|
|||
|
if(sp->m_Id != ptEnd->m_Id)
|
|||
|
{
|
|||
|
ptEnd = sp;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ptEnd = ep;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return !lstEdge.empty();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::addPoint( Point_Key key, sPoint* pPoint, bool bCheck /*= true*/ )
|
|||
|
{
|
|||
|
std::map<Point_Key, sPoint*>::iterator it = mPointsSrc.find(key);
|
|||
|
if (it != mPointsSrc.end() && bCheck)
|
|||
|
{
|
|||
|
// ASSERT(0);
|
|||
|
}
|
|||
|
|
|||
|
mPointsSrc[key] = pPoint;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::addArc( Arc_Key key , sArc* pArc , bool bCheck /*= true*/ )
|
|||
|
{
|
|||
|
bool bRe = !pArc->mPoints.empty();
|
|||
|
if (bRe)
|
|||
|
{
|
|||
|
//保存数据
|
|||
|
std::map<Arc_Key, sArc*>::iterator it = mArcsSrc.find(key);
|
|||
|
if (it != mArcsSrc.end() && bCheck)
|
|||
|
{
|
|||
|
//ASSERT(0);
|
|||
|
}
|
|||
|
//
|
|||
|
mArcsSrc[key] = pArc;
|
|||
|
|
|||
|
//保存过端点的linkData
|
|||
|
{
|
|||
|
//起点的半边数据
|
|||
|
sArcHalfEdge halfEdge(pArc);
|
|||
|
halfEdge.mDirection = EAD_Begin2End;
|
|||
|
//
|
|||
|
AddHaldEdge(halfEdge);
|
|||
|
|
|||
|
//终点的半边数据
|
|||
|
halfEdge.mDirection = EAD_End2Begin;
|
|||
|
//
|
|||
|
AddHaldEdge(halfEdge);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return bRe;
|
|||
|
}
|
|||
|
|
|||
|
void ClosedFinder::AddHaldEdge( const sArcHalfEdge &halfEdge )
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itHalfEdge(&halfEdge);
|
|||
|
const sPoint* pt = itHalfEdge.First();
|
|||
|
if (pt)
|
|||
|
{
|
|||
|
std::map<Arc_Key, sArcHalfEdge>* pData = getMapValue(mPointLinkData, pt->m_Id, true);
|
|||
|
if (pData)
|
|||
|
{
|
|||
|
(*pData) [halfEdge.mpArc->m_Id] = halfEdge;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//#define __LILIN_DEBUG_
|
|||
|
#ifdef __LILIN_DEBUG_
|
|||
|
#include <time.h>
|
|||
|
#endif
|
|||
|
|
|||
|
//搜索的最大多边形
|
|||
|
#define STEPMAX 60
|
|||
|
|
|||
|
//生成多边形,返回值为多边形的个数
|
|||
|
int ClosedFinder::GeneralPolygon()
|
|||
|
{
|
|||
|
mCurPolygon_Key = 1;
|
|||
|
|
|||
|
//int MaxSizeArr[STEPMAX * 2/* + 1*/] = {0};
|
|||
|
//{
|
|||
|
// //MaxSizeArr[0] = 2;
|
|||
|
// for(int i = 0; i < STEPMAX; i++)
|
|||
|
// {
|
|||
|
// MaxSizeArr[2 * i/*+1*/] = 2 + i; //第一次
|
|||
|
// MaxSizeArr[2*i + 1/*+1*/] = 2 + i; //第二次
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#ifdef __LILIN_DEBUG_
|
|||
|
time_t t = time( 0 );
|
|||
|
char tmp[64];
|
|||
|
strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",
|
|||
|
localtime(&t) );
|
|||
|
std::string str(tmp);
|
|||
|
#endif
|
|||
|
|
|||
|
int count = 0;
|
|||
|
int lastCount = 2;
|
|||
|
count = GetMaxEdgeSet();
|
|||
|
|
|||
|
while(count > 0)
|
|||
|
{
|
|||
|
for(int i = lastCount; i < count + 1; i++)
|
|||
|
{
|
|||
|
tCurMaxSize = i;
|
|||
|
tmapGen.clear();
|
|||
|
bool isExist = false;
|
|||
|
|
|||
|
std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >::iterator it = mPointLinkData.begin();
|
|||
|
for(; it != mPointLinkData.end(); it++)
|
|||
|
{
|
|||
|
sPolygon polygon;
|
|||
|
|
|||
|
std::map<Arc_Key, sArcHalfEdge>& linkDatas = it->second;
|
|||
|
|
|||
|
bool bReture = __GeneralPolygon(polygon, linkDatas);
|
|||
|
|
|||
|
if (bReture)
|
|||
|
{
|
|||
|
tmapGen[it->first] = it->first;
|
|||
|
isExist = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(isExist)
|
|||
|
{
|
|||
|
i--;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
lastCount = count +1;
|
|||
|
//itTmp = mPointLinkData.begin();
|
|||
|
//std::map<Arc_Key, sArcHalfEdge>& linkDatas = itTmp->second;
|
|||
|
//count = SearchGeneralPolygon(polygonTmp, linkDatas);
|
|||
|
count = GetMaxEdgeSet();
|
|||
|
if(lastCount > count)
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//for(int i = 0; i < STEPMAX; i++)
|
|||
|
//{
|
|||
|
// tCurMaxSize = i + 2;
|
|||
|
// tmapGen.clear();
|
|||
|
// bool isExist = false;
|
|||
|
//
|
|||
|
// std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >::iterator it = mPointLinkData.begin();
|
|||
|
// for(; it != mPointLinkData.end(); it++)
|
|||
|
// {
|
|||
|
// sPolygon polygon;
|
|||
|
//
|
|||
|
// std::map<Arc_Key, sArcHalfEdge>& linkDatas = it->second;
|
|||
|
//
|
|||
|
// bool bReture = __GeneralPolygon(polygon, linkDatas);
|
|||
|
//
|
|||
|
// if (bReture)
|
|||
|
// {
|
|||
|
// tmapGen[it->first] = it->first;
|
|||
|
// isExist = true;
|
|||
|
// }
|
|||
|
// }
|
|||
|
//
|
|||
|
// if(isExist)
|
|||
|
// {
|
|||
|
// i--;
|
|||
|
// }
|
|||
|
//}
|
|||
|
//2012-5-21 srq 针对bug 网格线,当输入的数据不能创建面时,系统总非法退出,建议给提示信息。 注:交点少于2个是不可能成面的
|
|||
|
if(mPolygons.size()<1)
|
|||
|
return 0;
|
|||
|
|
|||
|
ClearMaxEdgePolygon();
|
|||
|
__CombinPolygon();
|
|||
|
|
|||
|
|
|||
|
#ifdef __LILIN_DEBUG_
|
|||
|
{
|
|||
|
time_t t = time( 0 );
|
|||
|
char tmp[64];
|
|||
|
strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",
|
|||
|
localtime(&t) );
|
|||
|
std::string str1(tmp);
|
|||
|
|
|||
|
str = str + str1;
|
|||
|
}
|
|||
|
AfxMessageBox(str);
|
|||
|
#endif
|
|||
|
|
|||
|
return mPolygons.size();
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::__GeneralPolygon(sPolygon polygon, std::map<Arc_Key, sArcHalfEdge>& linkDatas )
|
|||
|
{
|
|||
|
bool bReturn = false;
|
|||
|
size_t iSize = polygon.mArcHalfEdge.size() + 1;
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*> tmapHalfEdgebyTime = SortPointLinkEdge(linkDatas);
|
|||
|
|
|||
|
|
|||
|
Point_Key polyFirstId = 0; //当前的多边形弧段集合的起始点号
|
|||
|
Arc_Key arcPreId = 0; //上一个ARC的ID
|
|||
|
if (!polygon.mArcHalfEdge.empty())
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itArcHalfEdge(&(*polygon.mArcHalfEdge.begin()));
|
|||
|
polyFirstId = itArcHalfEdge.First()->m_Id;
|
|||
|
|
|||
|
arcPreId = polygon.mArcHalfEdge.rbegin()->mpArc->m_Id;
|
|||
|
}
|
|||
|
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*>::const_iterator itLink = tmapHalfEdgebyTime.begin();
|
|||
|
for(; itLink != tmapHalfEdgebyTime.end(); ++itLink)
|
|||
|
{
|
|||
|
sPolygon polygonCur(polygon); //创建临时多边形,防止污源被污染
|
|||
|
//
|
|||
|
const sArcHalfEdge& halEdge = *itLink->second;
|
|||
|
const sArc *mpArc = halEdge.mpArc;
|
|||
|
|
|||
|
if (arcPreId == mpArc->m_Id) {continue;} //不能为上一段线
|
|||
|
//
|
|||
|
if (mpArc->mTimeofSearch == 2)
|
|||
|
{
|
|||
|
//此边及其以后的所有边为死边,返回(因为已经排过顺序)
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itArcHalfEdge(&halEdge);
|
|||
|
Point_Key ptFirstId = itArcHalfEdge.First()->m_Id;
|
|||
|
Point_Key ptEndId = itArcHalfEdge.GetEnd()->m_Id;
|
|||
|
|
|||
|
if (tmapGen.find(polyFirstId) == tmapGen.end() &&
|
|||
|
tmapGen.find(ptFirstId) == tmapGen.end()) //不为生成过的点
|
|||
|
{
|
|||
|
if (iSize == tCurMaxSize)
|
|||
|
{
|
|||
|
//判断最后一点和第一点是否相等,是的话,则加入到结果封闭区域中
|
|||
|
if (ptEndId == polyFirstId)
|
|||
|
{
|
|||
|
//恭喜,找到封闭的区域
|
|||
|
//if (tCurMaxSize == 2) //TODO : 为两边的时候比较特殊
|
|||
|
//{
|
|||
|
//tmapGen[ptFirstId] = ptFirstId;
|
|||
|
//}
|
|||
|
|
|||
|
AddEdge(polygonCur, halEdge);
|
|||
|
|
|||
|
if(_AddPolygon(polygonCur))
|
|||
|
{
|
|||
|
bReturn = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//失败,不处理
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (polygonCur.ExistPoint(ptEndId))
|
|||
|
{
|
|||
|
continue;
|
|||
|
//continue;
|
|||
|
}
|
|||
|
if (tCurMaxSize > 2 && polyFirstId == ptEndId)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
//不满足最大边,得到最后一点,递归(深度优先)
|
|||
|
AddEdge(polygonCur, halEdge);
|
|||
|
//polygonCur.AddEdge(halEdge);
|
|||
|
|
|||
|
std::map<Arc_Key, sArcHalfEdge>* pData = getMapValue(mPointLinkData, ptEndId, false);
|
|||
|
if (pData)
|
|||
|
{
|
|||
|
bReturn = __GeneralPolygon(polygonCur, *pData);
|
|||
|
if (bReturn)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// ASSERT(0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return bReturn;
|
|||
|
}
|
|||
|
|
|||
|
//搜索多边形, 返回多边形边数,没有 返回-1
|
|||
|
int ClosedFinder::SearchGeneralPolygon(sPolygon polygon, std::map<Arc_Key, sArcHalfEdge>& linkDatas )
|
|||
|
{
|
|||
|
bool bReturn = false;
|
|||
|
size_t iSize = polygon.mArcHalfEdge.size() + 1;
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*> tmapHalfEdgebyTime = SortPointLinkEdge(linkDatas);
|
|||
|
|
|||
|
|
|||
|
Point_Key polyFirstId = 0; //当前的多边形弧段集合的起始点号
|
|||
|
Arc_Key arcPreId = 0; //上一个ARC的ID
|
|||
|
if (!polygon.mArcHalfEdge.empty())
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itArcHalfEdge(&(*polygon.mArcHalfEdge.begin()));
|
|||
|
polyFirstId = itArcHalfEdge.First()->m_Id;
|
|||
|
|
|||
|
arcPreId = polygon.mArcHalfEdge.rbegin()->mpArc->m_Id;
|
|||
|
}
|
|||
|
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*>::const_iterator itLink = tmapHalfEdgebyTime.begin();
|
|||
|
for(; itLink != tmapHalfEdgebyTime.end(); ++itLink)
|
|||
|
{
|
|||
|
sPolygon polygonCur(polygon); //创建临时多边形,防止污源被污染
|
|||
|
//
|
|||
|
const sArcHalfEdge& halEdge = *itLink->second;
|
|||
|
const sArc *mpArc = halEdge.mpArc;
|
|||
|
|
|||
|
if (arcPreId == mpArc->m_Id) {continue;} //不能为上一段线
|
|||
|
//
|
|||
|
if (mpArc->mTimeofSearch == 2)
|
|||
|
{
|
|||
|
//此边及其以后的所有边为死边,返回(因为已经排过顺序)
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itArcHalfEdge(&halEdge);
|
|||
|
Point_Key ptFirstId = itArcHalfEdge.First()->m_Id;
|
|||
|
Point_Key ptEndId = itArcHalfEdge.GetEnd()->m_Id;
|
|||
|
|
|||
|
if (tmapGen.find(polyFirstId) == tmapGen.end() &&
|
|||
|
tmapGen.find(ptFirstId) == tmapGen.end()) //不为生成过的点
|
|||
|
{
|
|||
|
//判断最后一点和第一点是否相等,是的话,则加入到结果封闭区域中
|
|||
|
if (ptEndId == polyFirstId)
|
|||
|
{
|
|||
|
//恭喜,找到封闭的区域
|
|||
|
//if (tCurMaxSize == 2) //TODO : 为两边的时候比较特殊
|
|||
|
//{
|
|||
|
//tmapGen[ptFirstId] = ptFirstId;
|
|||
|
//}
|
|||
|
|
|||
|
AddEdge(polygonCur, halEdge);
|
|||
|
|
|||
|
//return polygonCur.mArcHalfEdge.size();
|
|||
|
polygonCur.CalMark();
|
|||
|
if(tmapExistPolygon.find(polygonCur.mMarkType) == tmapExistPolygon.end())
|
|||
|
{
|
|||
|
return polygonCur.mArcHalfEdge.size();
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (polygonCur.ExistPoint(ptEndId))
|
|||
|
{
|
|||
|
int index = polygonCur.GetPointIndex(ptEndId);
|
|||
|
return polygonCur.mArcHalfEdge.size() - index + 1;
|
|||
|
//continue;
|
|||
|
}
|
|||
|
if (tCurMaxSize > 2 && polyFirstId == ptEndId)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
//不满足最大边,得到最后一点,递归(深度优先)
|
|||
|
AddEdge(polygonCur, halEdge);
|
|||
|
//polygonCur.AddEdge(halEdge);
|
|||
|
|
|||
|
std::map<Arc_Key, sArcHalfEdge>* pData = getMapValue(mPointLinkData, ptEndId, false);
|
|||
|
if (pData)
|
|||
|
{
|
|||
|
int count = SearchGeneralPolygon(polygonCur, *pData);
|
|||
|
if (count > 0)
|
|||
|
{
|
|||
|
return count;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// ASSERT(0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int ClosedFinder::GetMaxEdgeSet()
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
int lastCount = 2;
|
|||
|
|
|||
|
std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >::iterator itTmp = mPointLinkData.begin();
|
|||
|
|
|||
|
for(; itTmp != mPointLinkData.end(); itTmp++)
|
|||
|
{
|
|||
|
sPolygon polygonTmp;
|
|||
|
std::map<Arc_Key, sArcHalfEdge>& linkDatas = itTmp->second;
|
|||
|
count = SearchGeneralPolygon(polygonTmp, linkDatas);
|
|||
|
if(count > 0)
|
|||
|
{
|
|||
|
return count;
|
|||
|
}
|
|||
|
}
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::_AddPolygon( sPolygon &polygonCur)
|
|||
|
{
|
|||
|
polygonCur.m_Id = mCurPolygon_Key;
|
|||
|
polygonCur.CalMark();
|
|||
|
|
|||
|
//
|
|||
|
if(!(/*tCurMaxSize == 3 &&*/ ExistPolygon(polygonCur)))//没有存在多边形
|
|||
|
{
|
|||
|
|
|||
|
// 判断多边形的边是否都在 border中 yc 20130724
|
|||
|
bool isAll = true;
|
|||
|
std::vector<sArcHalfEdge>::iterator iter = polygonCur.mArcHalfEdge.begin();
|
|||
|
for(; iter != polygonCur.mArcHalfEdge.end(); iter ++)
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
for(; i < (int)border.size(); i++)
|
|||
|
{
|
|||
|
if(border[i] == iter->mpArc->m_IdSrc)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if( i == (int)border.size())
|
|||
|
{
|
|||
|
isAll = false;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(isAll)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
mCurPolygon_Key++ ;
|
|||
|
//把多边形的边的计算数加1
|
|||
|
#ifdef _DEBUG
|
|||
|
std::string str;
|
|||
|
#endif
|
|||
|
{
|
|||
|
#ifdef _DEBUG
|
|||
|
//str.Format(_T("(%d): "), polygonCur.m_Id);
|
|||
|
str = "(" + std::to_string(polygonCur.m_Id) + "): ";
|
|||
|
#endif
|
|||
|
std::vector<sArcHalfEdge>::iterator itpl = polygonCur.mArcHalfEdge.begin();
|
|||
|
polygonCur.mIsIland = true;
|
|||
|
for(; itpl != polygonCur.mArcHalfEdge.end(); itpl ++)
|
|||
|
{
|
|||
|
itpl->mpArc->mTimeofSearch += 1;
|
|||
|
//去掉孤岛标志
|
|||
|
sArcHalfEdge& halfEdge = *itpl;
|
|||
|
PostIsland(polygonCur, halfEdge);
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator halfIter(&(*itpl));
|
|||
|
std::string strT;
|
|||
|
//strT.Format(_T("%d(%c,%d-%d), "), itpl->mpArc->m_Id, 'a' + itpl->mpArc->m_Id - 1,
|
|||
|
// halfIter.First()->m_Id, halfIter.GetEnd()->m_Id);
|
|||
|
char arcChar = 'a' + itpl->mpArc->m_Id - 1;
|
|||
|
strT = std::to_string(itpl->mpArc->m_Id) + "(" + arcChar + "," +
|
|||
|
std::to_string(halfIter.First()->m_Id) + "-" + std::to_string(halfIter.GetEnd()->m_Id) + "), ";
|
|||
|
|
|||
|
str = str + strT;
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//如果为孤岛,需要把孤岛的边再次加1,这样,就不会再次搜索
|
|||
|
if (polygonCur.mIsIland)
|
|||
|
{
|
|||
|
std::vector<sArcHalfEdge>::iterator itpl = polygonCur.mArcHalfEdge.begin();
|
|||
|
for(; itpl != polygonCur.mArcHalfEdge.end(); itpl ++)
|
|||
|
{
|
|||
|
itpl->mpArc->mTimeofSearch += 1;
|
|||
|
}
|
|||
|
#ifdef _DEBUG
|
|||
|
str = str + "(island)";
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
mPolygons[polygonCur.m_Id] = polygonCur;
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
str = str + "\n";
|
|||
|
//OutputDebugString(str.c_str());
|
|||
|
#endif
|
|||
|
|
|||
|
//缓存所有两变形面
|
|||
|
_PostPolygon2edge(polygonCur);
|
|||
|
|
|||
|
//AfxMessageBox(str);
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::ExistPolygon( const sPolygon &polygonCur )
|
|||
|
{
|
|||
|
bool bExist = false;
|
|||
|
std::map<T_MARK_TYPE, Polygon_Key>::const_iterator it = tmapExistPolygon.find(polygonCur.mMarkType); //已经被生成过的多边形,
|
|||
|
|
|||
|
if (it != tmapExistPolygon.end())//存在
|
|||
|
{
|
|||
|
bExist = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//缓存已经存在的东东
|
|||
|
tmapExistPolygon[polygonCur.mMarkType] = polygonCur.m_Id;
|
|||
|
}
|
|||
|
|
|||
|
return bExist;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void ClosedFinder::PostIsland( sPolygon &polygonCur, sArcHalfEdge& halfEdge )
|
|||
|
{
|
|||
|
if (polygonCur.mIsIland)
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itHalfEdge(&(halfEdge));
|
|||
|
const sPoint* pt = itHalfEdge.First();
|
|||
|
const std::map<Arc_Key, sArcHalfEdge>*pDate = getMapValue_Const
|
|||
|
<Point_Key, std::map<Arc_Key, sArcHalfEdge> >(mPointLinkData, pt->m_Id);
|
|||
|
//
|
|||
|
if (pDate && pDate->size() > 2) //非孤岛
|
|||
|
{
|
|||
|
polygonCur.mIsIland = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TimeofSearch ClosedFinder::_GetMaxTimeOfSearch( sPolygon &polygonCur)
|
|||
|
{
|
|||
|
TimeofSearch mTimeofSearch = 0;
|
|||
|
std::vector<sArcHalfEdge>::const_iterator it = polygonCur.mArcHalfEdge.begin();
|
|||
|
for(; it != polygonCur.mArcHalfEdge.end(); it++)
|
|||
|
{
|
|||
|
mTimeofSearch = max(it->mpArc->mTimeofSearch, mTimeofSearch);
|
|||
|
}
|
|||
|
return mTimeofSearch;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*> ClosedFinder::SortPointLinkEdge( std::map<Arc_Key, sArcHalfEdge> &linkDatas )
|
|||
|
{
|
|||
|
std::multimap<TimeofSearch, sArcHalfEdge*> tmapHalfEdgebyTime;
|
|||
|
tmapHalfEdgebyTime.clear();
|
|||
|
std::map<Arc_Key, sArcHalfEdge>::iterator itLink = linkDatas.begin();
|
|||
|
for(; itLink != linkDatas.end(); itLink++)
|
|||
|
{
|
|||
|
TimeofSearch timesS = itLink->second.mpArc->mTimeofSearch;
|
|||
|
//tmapHalfEdgebyTime.insert(std::make_pair<TimeofSearch, sArcHalfEdge*>(timesS, &itLink->second)); //pj change
|
|||
|
tmapHalfEdgebyTime.insert(std::make_pair(timesS, &itLink->second));
|
|||
|
}
|
|||
|
|
|||
|
return tmapHalfEdgebyTime;
|
|||
|
}
|
|||
|
|
|||
|
void ClosedFinder::_PostPolygon2edge(const sPolygon &polygonCur )
|
|||
|
{
|
|||
|
//return;
|
|||
|
if (polygonCur.mArcHalfEdge.size() == 2)
|
|||
|
{
|
|||
|
CompositeKey compKey(0,0);
|
|||
|
if (polygonCur.GetBE_CompositeKey(compKey))
|
|||
|
{
|
|||
|
//mp
|
|||
|
std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >* pCompData =
|
|||
|
getMapValue<CompositeKey, std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> > >
|
|||
|
(mmapLinkArcs2, compKey, true);; //弧段所属的等同段
|
|||
|
|
|||
|
if (pCompData)
|
|||
|
{
|
|||
|
polygonCur.GetBE_HalfEdge(*pCompData);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
void ClosedFinder::AddEdge( sPolygon &polygonCur, const sArcHalfEdge& halEdge )
|
|||
|
{
|
|||
|
sArcHalfEdge halEdgeT(halEdge);
|
|||
|
//判断最后当前的半边数据结构是否存在两边形
|
|||
|
if (!mmapLinkArcs2.empty() && !polygonCur.mArcHalfEdge.empty())
|
|||
|
{
|
|||
|
sArcHalfEdge::ArcHalfEdge_const_iterator itHalf(&halEdgeT);
|
|||
|
CompositeKey compKey(0,0);
|
|||
|
compKey.mKey1 = min(itHalf.First()->m_Id, itHalf.GetEnd()->m_Id);
|
|||
|
compKey.mKey2 = max(itHalf.First()->m_Id, itHalf.GetEnd()->m_Id);
|
|||
|
|
|||
|
//
|
|||
|
const std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >* pCompData =
|
|||
|
getMapValue_Const<CompositeKey, std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> > >
|
|||
|
(mmapLinkArcs2, compKey);; //弧段所属的等同段
|
|||
|
|
|||
|
//存在,求最小的距离
|
|||
|
if (pCompData)
|
|||
|
{
|
|||
|
//std::map<Point_Key, std::map<Arc_Key, sArcHalfEdge> >::const_iterator& itArcs = pCompData->find(compKey.mKey1); //pj
|
|||
|
auto itArcs = pCompData->find(compKey.mKey1);
|
|||
|
if (itArcs != pCompData->end())
|
|||
|
{
|
|||
|
const std::map<Arc_Key, sArcHalfEdge>& arcs = itArcs->second;
|
|||
|
std::map<double/*distance*/, const sArcHalfEdge*> tHalfByDis;
|
|||
|
|
|||
|
gp_Point pt(0,0,0);
|
|||
|
polygonCur.GetAverageMarkPoint(pt);
|
|||
|
|
|||
|
{
|
|||
|
std::map<Arc_Key, sArcHalfEdge>::const_iterator it = arcs.begin();
|
|||
|
for(; it != arcs.end(); it++)
|
|||
|
{
|
|||
|
const gp_Point& ptCur = it->second.mpArc->mMarkPoint;
|
|||
|
double dbl = (pt.X() - ptCur.X())*((pt.X() - ptCur.X())) +
|
|||
|
(pt.Y() - ptCur.Y())*(pt.Y() - ptCur.Y()) +
|
|||
|
(pt.Z() - ptCur.Z()) * (pt.Z() - ptCur.Z());
|
|||
|
|
|||
|
tHalfByDis[dbl] = &it->second;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
if (!tHalfByDis.empty())
|
|||
|
{
|
|||
|
std::map<double, const sArcHalfEdge*>::const_iterator it = tHalfByDis.begin();
|
|||
|
for(; it != tHalfByDis.end(); it ++)
|
|||
|
{
|
|||
|
const sArcHalfEdge* psArcHalfEdge = it->second;
|
|||
|
if (psArcHalfEdge->mpArc->mTimeofSearch < 2 &&
|
|||
|
!polygonCur.ExistArc(psArcHalfEdge->mpArc->m_Id))
|
|||
|
{
|
|||
|
halEdgeT = * it->second;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//添加
|
|||
|
polygonCur.AddEdge(halEdgeT);
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::__CombinPolygon()
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
std::map<Polygon_Key, sPolygon >::const_iterator itpl = mPolygons.begin();
|
|||
|
for(; itpl != mPolygons.end(); itpl++)
|
|||
|
{
|
|||
|
const sPolygon& pl = itpl->second;
|
|||
|
|
|||
|
const std::vector<sArcHalfEdge>& mArcHalfEdge = pl.mArcHalfEdge;
|
|||
|
if (!mArcHalfEdge.empty())
|
|||
|
{
|
|||
|
std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > >& lstPolygon =
|
|||
|
*getMapValue<Polygon_Key, std::list<std::pair<Arc_Key, std::list<sArcHalfEdge> > > >(mPolygonsCombin, itpl->first, true);
|
|||
|
|
|||
|
std::pair<Arc_Key, std::list<sArcHalfEdge> > pairEdge;
|
|||
|
std::vector<sArcHalfEdge>::const_iterator it = mArcHalfEdge.begin();
|
|||
|
//
|
|||
|
const sArcHalfEdge* edgeSrc = &(*it++);
|
|||
|
pairEdge.first = edgeSrc->mpArc->m_IdSrc;
|
|||
|
pairEdge.second.push_back(*edgeSrc);
|
|||
|
for(; it != mArcHalfEdge.end(); it++)
|
|||
|
{
|
|||
|
const sArcHalfEdge* edgeCur = &(*it);
|
|||
|
if (edgeCur->mpArc->m_IdSrc == pairEdge.first)
|
|||
|
{
|
|||
|
pairEdge.second.push_back(*edgeCur);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
lstPolygon.push_back(pairEdge);
|
|||
|
//
|
|||
|
edgeSrc = edgeCur;
|
|||
|
pairEdge.first = edgeSrc->mpArc->m_IdSrc;
|
|||
|
pairEdge.second.clear();
|
|||
|
pairEdge.second.push_back(*edgeSrc);
|
|||
|
}
|
|||
|
}
|
|||
|
//尾首合并
|
|||
|
//--- yangchen 2012.5.15 start
|
|||
|
std::pair<Arc_Key, std::list<sArcHalfEdge> > pairEdgeTmp = lstPolygon.front();
|
|||
|
if(pairEdgeTmp.first == pairEdge.first)
|
|||
|
{
|
|||
|
std::list<sArcHalfEdge> edgeSet = pairEdge.second;
|
|||
|
std::list<sArcHalfEdge> edgeSetTmp = pairEdgeTmp.second;
|
|||
|
for(std::list<sArcHalfEdge>::reverse_iterator iter = edgeSet.rbegin(); iter != edgeSet.rend(); iter++)
|
|||
|
{
|
|||
|
pairEdgeTmp.second.push_front(*iter);
|
|||
|
}
|
|||
|
lstPolygon.pop_front();
|
|||
|
lstPolygon.push_front(pairEdgeTmp);
|
|||
|
}
|
|||
|
else
|
|||
|
//--- yangchen 2012.5.15 end
|
|||
|
lstPolygon.push_back(pairEdge);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::ClearMaxEdgePolygon()
|
|||
|
{
|
|||
|
std::map<Polygon_Key, sPolygon >::reverse_iterator itpl = mPolygons.rbegin();
|
|||
|
|
|||
|
sPolygon pl = itpl->second;
|
|||
|
Polygon_Key ikey = itpl->first;
|
|||
|
vector<Point_Key> keySet1 = pl.GetPointKeySet();
|
|||
|
//CompositeKey ckey;
|
|||
|
//pl.GetBE_CompositeKey(ckey);
|
|||
|
|
|||
|
itpl++;
|
|||
|
for (;itpl!=mPolygons.rend();++itpl)
|
|||
|
{
|
|||
|
if(IsIncludeClosedPolygon(keySet1,itpl->second.GetPointKeySet()))
|
|||
|
{
|
|||
|
mPolygons.erase(ikey);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool ClosedFinder::IsIncludeClosedPolygon(vector<Point_Key>& keySet1, vector<Point_Key> keySet2)
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
|
|||
|
for(vector<Point_Key>::iterator iter1 = keySet1.begin();iter1 != keySet1.end(); iter1++)
|
|||
|
{
|
|||
|
|
|||
|
for(vector<Point_Key>::iterator iter2 = keySet2.begin();iter2 != keySet2.end(); iter2++)
|
|||
|
{
|
|||
|
if(*iter1 == *iter2)
|
|||
|
{
|
|||
|
count++;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return count > 2;
|
|||
|
}
|