主页 > 原创 > CRgn区域取边界点依次存入到链表

CRgn区域取边界点依次存入到链表

CRgn没有现成的获取所有边界点的方法,需要对GetRegionData函数数据进行转换获取到所有边界点,方法如下所示:

1.原理
GetRegionData(pRgnD, nRect)函数会将所有构成区域的矩形写入到nRect数组中,排列方式为由左向右,由上向下。
类似于如下图所示:
2014-04-18_175254
如果获取了矩形通过cad画出来效果会非常直观。
将所有左边矩形的左上左下记录,右上右下记录就可以得到区域边界,但是内部的空洞需要特殊处理,下面处理空洞的代码部分只是一个简单的处理。(其中坐标转换计算与本文无关)
2.代码实现

typedef vector<vector<CRect>> CRectMap;
struct RealCoordinate{
 double x;
 double y;
};

typedef deque<RealCoordinate> PointList;

typedef struct T_Region{
 PointList boarder;
  vector<PointList> inner;
};
CRgn* rgn = &boundingRgn;
CRectMap mRectMap;
if (rgn->m_hObject!=NULL)
{
 RGNDATA *pRgnD;
 int nRect;
  nRect = rgn->GetRegionData(NULL, 0);
  pRgnD = (RGNDATA *) new char[nRect];

  CRect *pRect = (CRect *) &pRgnD->Buffer;

  nRect = rgn->GetRegionData(pRgnD, nRect);

 int blockCount = 0;
 int maxCount = 0;
 int lastTop=pRect[0].top;
 int lastBot=pRect[0].bottom;

  mRectMap.clear();

 vector<CRect> tmpRect;
  for (int i=0;i<pRgnD->rdh.nCount;i++)
 {
   if (lastTop!=pRect[i].top && lastBot!=pRect[i].bottom)
    {
     mRectMap.push_back(tmpRect);
      tmpRect.clear();
    }
   tmpRect.push_back(pRect[i]);
    lastTop=pRect[i].top;
   lastBot=pRect[i].bottom;
  }

 mRectMap.push_back(tmpRect);

  RealCoordinate point;

 T_Region region;
  REAL base_left = BorderRect.GetLeft();
  REAL base_top = BorderRect.GetTop();
  for (int i=0; i<mRectMap.size();i++)
  {
   point.x = (mRectMap[i][0].left-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
    point.y = (BorderRect.Height - (mRectMap[i][0].top-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
    region.boarder.push_back(point);
    point.x = (mRectMap[i][0].left-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
    point.y = (BorderRect.Height - (mRectMap[i][0].bottom-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
   region.boarder.push_back(point);
    point.x = (mRectMap[i][mRectMap[i].size()-1].right-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
    point.y = (BorderRect.Height - (mRectMap[i][mRectMap[i].size()-1].top-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
   region.boarder.push_front(point);
   point.x = (mRectMap[i][mRectMap[i].size()-1].right-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
    point.y = (BorderRect.Height - (mRectMap[i][mRectMap[i].size()-1].bottom-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
    region.boarder.push_front(point);
 }
 int maxSize=0;
  for (int i=0;i<mRectMap.size();i++)
 {
   int size = mRectMap[i].size();
    maxSize=maxSize<size?size:maxSize;
  }

 PointList pointList;
  for (int j=1; j<maxSize;j++)
  {
   bool _start = false;
    for (int i=0;i<mRectMap.size();i++)
   {
     if (mRectMap[i].size()>j)
     {
       if (!_start)
        {
         _start = true;
          pointList.clear();
        }
       point.x = (mRectMap[i][j-1].right-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
       point.y = (BorderRect.Height - (mRectMap[i][j-1].top-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
        pointList.push_back(point);
       point.x = (mRectMap[i][j-1].right-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
       point.y = (BorderRect.Height - (mRectMap[i][j-1].bottom-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
       pointList.push_back(point);
       point.x = (mRectMap[i][j].left-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
        point.y = (BorderRect.Height - (mRectMap[i][j].top-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
        pointList.push_front(point);
        point.x = (mRectMap[i][j].left-base_left)*m_Ratio*(RealHeight/m_OriginHeight);
        point.y = (BorderRect.Height - (mRectMap[i][j].bottom-base_top))*m_Ratio*(RealHeight/m_OriginHeight);
       pointList.push_front(point);
      }
     else
      {
       if (_start)
       {
         region.inner.push_back(pointList);
          _start = false;
       }
     }
   }
 }
}

Tags: crgn 边界

发表评论

电子邮件地址不会被公开。 必填项已用*标注