mfc 多边形裁剪算法

7 篇文章 9 订阅

多边形裁剪

效果截图:

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相关直线、圆、椭圆、多边形、多边形填充、裁剪直线可以关注我的博客

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值