mfc 多边形裁剪算法

论坛 期权论坛 脚本     
匿名网站用户   2020-12-20 11:12   11   0

多边形裁剪

效果截图:

1.头文件定义:

enum Boundary{Left, Right, Bottom, Top};

int cj_line_x1;//裁剪直线时原直线的坐标
int cj_line_x2;
int cj_line_y1;
int cj_line_y2;

CPoint cj_win1;//裁剪窗口坐标,矩形窗口的对角坐标
CPoint cj_win2;

//多边形裁剪
int dbx_count;
CPoint ps[5];//这里以画五个顶点的多变形为例,而且不必初始化

以上定义的一定要在构造函数里初始化,不然会报错

具体实现:

//判断点在裁剪框内外
int CquhongjuanView::Inside(POINT p, Boundary b, POINT wMin, POINT wMax)
 {   
  switch (b)
  {
  case Left:
   if (p.x<wMin.x) return (false);
   break;
  case Right:
   if (p.x>wMax.x) return (false);
   break;
  case Bottom:
   if (p.y<wMin.y) return (false);
   break;
  case Top:
   if (p.y>wMax.y) return (false);
   break;
  }
  return true;
 }/*Inside*/

 /* 求相交的点 */
 POINT CquhongjuanView::Intersect(POINT p1, POINT p2, Boundary b, POINT  wMin, POINT wMax)
 {
  POINT iPt;
  float m;
  if (p1.x != p2.x) m = (p2.y - p1.y)*1.0 / (p2.x - p1.x);
  switch (b) {
  case Left:
   iPt.x = wMin.x;
   iPt.y = p2.y + (wMin.x - p2.x)*m;
   break;
  case Right:
   iPt.x = wMax.x;
   iPt.y = p2.y + (wMax.x - p2.x)*m;
   break;
  case Bottom:
   iPt.y = wMin.y;
   if (p1.x != p2.x)iPt.x = p2.x + (wMin.y - p2.y) / m;
   else iPt.x = p2.x;
   break;
  case Top:
   iPt.y = wMax.y;
   if (p1.x != p2.x) iPt.x = p2.x + (wMax.y - p2.y) / m;
   else iPt.x = p2.x;
   break;
  }
  return iPt;
 }/*Intersect*/

 //按边裁剪
 int Cquhongjuaniew::edgeCliper(Boundary b, POINT wMin, POINT wMax, POINT *pIn, int cnt, POINT *pOut) {

  POINT s;
  int i, Outcnt = 0;
  s = pIn[0];
  for (i = 1; i <= cnt; i++)
  {
   if (!Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
   {
    pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
    Outcnt++;
    pOut[Outcnt] = pIn[i];
    Outcnt++;
   }
   else if (Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
   {
    pOut[Outcnt] = pIn[i];
    Outcnt++;
   }
   else if (Inside(s, b, wMin, wMax) && (!Inside(pIn[i], b, wMin, wMax)))
   {
    pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
    Outcnt++;
   }
   s = pIn[i];
  }
  return Outcnt;
 }/*edgeCliper*/

 /*   多边形裁剪  */
 void CquhongjuanView::clipPolygon(CDC * pDC){

  int i, cnt, Outcnt, b;
     //多写了第一个点是为了使得最后一个点与第一个点连起来
  POINT points[6] = { { ps[0].x,ps[0].y },{  ps[1].x,ps[1].y },{  ps[2].x,ps[2].y },{  ps[3].x,ps[3].y },
  {  ps[4].x,ps[4].y },{ ps[0].x,ps[0].y} };

  cnt = 5;

  POINT pOut[20], pIn[20];
  POINT wMin = { 100,100 }, wMax = { 300,300 };



  for (i = 0; i < 4 * cnt; i++)
  {
   pIn[i].x = 0;
   pIn[i].y = 0;
   pOut[i].x = 0;
   pOut[i].y = 0;
  }
  for (i = 0; i <= cnt; i++) pIn[i] = points[i];

  for (b = 0; b < 4; b++)
  {
   Outcnt = edgeCliper(Boundary(b), wMin, wMax, pIn, cnt, pOut);
   for (i = 0; i < Outcnt; i++)  
    pIn[i] = pOut[i];
   pIn[Outcnt] = pOut[0];
   cnt = Outcnt;
  }

  pDC->Rectangle(wMin.x, wMin.y, wMax.x, wMax.y);
  pDC->Polygon(pOut, cnt);
  return;
 }/* clipPolygon */

/*  显示未裁剪的多边形和框 */
 void CquhongjuanView::showUnclipPolygon(CDC * pDC){

  POINT points[5] = { { ps[0].x,ps[0].y },{  ps[1].x,ps[1].y },{  ps[2].x,ps[2].y },{  ps[3].x,ps[3].y },
  {  ps[4].x,ps[4].y } };
  //POINT points[8];
  
  POINT wMin = { 100,100 }, wMax = { 300,300 };

  CBrush * pOldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH);
  pDC->Rectangle(wMin.x, wMin.y, wMax.x, wMax.y);
  pDC->Polygon(points, 5);
  pDC->SelectObject(pOldBrush);

 }

可能有些定义不明确,可以根据上下文语境推测,主要是这个做起来有点烦,就懒得写了,体谅一下

ps:mfc相关直线、圆、椭圆、多边形、多边形填充、裁剪直线可以关注我的博客

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP