CGAL求最小外包矩形

有两种所谓的最小外包矩形,第一种通过求所有节点的最小与最大xy来求的,这种叫与坐标轴平行的最小外包矩形;另外一种则是本文说的这种,与范围的形状与走势有关的,叫非坐标轴平行的最小外包矩形,效果如下图所示:
CGAL求最小外包矩形 > image2018-8-21_10-33-22.png
/// 这里做测试,只选中LWPOLYLINLE,也就是CAD中的多段线实体

struct resbuf* rb = ads_buildlist(RTDXF0, _T("LWPOLYLINE"), RTNONE);
ads_name ent, ssLines;

if (RTNORM != ads_ssget(NULL, NULL, NULL, rb, ssLines))
{
       ads_relrb(rb);
      return;
}
ads_relrb(rb);
AcDbObjectId id;
Adesk::Int32 len = 0, l = 0;
ads_sslength(ssLines, &len);
std::vector<Point_2> nodesn,nodes_hull;

////////这里遍历选择集获取所有实体的节点
for (l = 0;l < len;l++)
{
      ads_ssname(ssLines, l, ent);
      if (Acad::eOk != acdbGetObjectId(id, ent))
      {
            continue;
      }
      AcDbEntity* pEnt = NULL;
      if (acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead) != Acad::eOk)
      {
            continue;
      }
      if (!pEnt->isKindOf(AcDbPolyline::desc()))
      {
            continue;
      }
      AcDbPolyline* pLine = AcDbPolyline::cast(pEnt);
      AcGePoint3d ptS, ptE;
      for (int idx = 0;idx < pLine->numVerts();idx++)
      {
            AcGePoint2d pt;
            pLine->getPointAt(idx, pt);
            nodesn.push_back(Point_2(pt.x, pt.y));
            acutPrintf(_T("Random coordinate:%d: %.3lf %.3lf\n"), idx+1,pt.x, pt.y);
      }
      pEnt->close();
      break;
}
ads_ssfree(ssLines);
///发现在求最小外接矩形的时候传入的点不能有坐标一直的点,而且点的方向必须是逆时针排列
///所以这里先求节点的凸包,然后通过Polygon_2来把非逆时针排列的节点纠正成逆时针
CGAL::convex_hull_2(nodesn.begin(), nodesn.end(), std::back_inserter(nodes_hull));

Polygon_2 p;
std::vector<Point_2>::iterator itn;
for (itn = nodes_hull.begin();itn != nodes_hull.end();itn++)
{
      p.push_back(*itn);
}
AcGePoint2dArray nodes;
for (int i = 0;i < p.size();i++)
{
      double x = CGAL::to_double(p.vertex(i).x());
      double y = CGAL::to_double(p.vertex(i).y());
      nodes.append(AcGePoint2d(x, y));
}
Common::DrawPolyline2D(nodes, true);
if (p.is_clockwise_oriented())
{
      p.reverse_orientation();
}
Polygon_2 m_p;
CGAL::min_rectangle_2(p.vertices_begin(), p.vertices_end(), std::back_inserter(m_p));
Polygon_2::Vertex_const_iterator it;
nodes.removeAll();
for (it = m_p.vertices_begin(); it != m_p.vertices_end(); it++)
{
      double x = CGAL::to_double((*it).x());
      double y = CGAL::to_double((*it).y());
      nodes.append(AcGePoint2d(x, y));
}

Common::DrawPolyline2D(nodes, true);

posted on 2018-08-21 15:08  baiqi  阅读(367)  评论(0编辑  收藏  举报

导航