欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mfc 多边形裁剪算法

程序员文章站 2022-03-13 14:50:47
...

多边形裁剪

效果截图:

mfc 多边形裁剪算法mfc 多边形裁剪算法

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