自己写的一个矩形裁剪功能 冷夜

对线段进行裁剪,返回裁剪后的线段,完全自己想的没什么优化,应该还有些BUG暂时不做深究,效果图如下

未裁剪:

裁剪后:

代码:

//点
typedef struct sc_point
{
	int x,y;
	sc_point(){x=0;y=0;};
}ScPoint;
//线
typedef struct sc_line
{
	ScPoint point1,point2;
}ScLine;

bool CEnginApp::ClearLine(const ScLine *line,ScLine &line2)
{
	if (!line)
		return false;
	
	int x1=0,x2=0,y1=0,y2=0,temp=0;
	x1=line->point1.x;
	x2=line->point2.x;
	y1=line->point1.y;
	y2=line->point2.y;

	//从小到大排序便于最后替换端点
	if (x1>x2)
	{
		temp=x1;
		x1=x2;
		x2=temp;

		temp=y1;
		y1=y2;
		y2=temp;
	}

	line2.point1.x=x1;
	line2.point1.y=y1;
	line2.point2.x=x2;
	line2.point2.y=y2;

	float dx=x2-x1;
	float dy=y2-y1;
	//处理平行线和垂直线
	if(dx==0)
	{
		if (y1>y2)
		{
			temp=x1;
			x1=x2;
			x2=temp;

			temp=y1;
			y1=y2;
			y2=temp;

			ScPoint ptem=line2.point1;
			line2.point1=line2.point2;
			line2.point2=ptem;
		}
		if (x1>clearRect.left&&x1<clearRect.right)
		{
			if (y1<clearRect.top)
			{
				line2.point1.y=clearRect.top;
			}
			if (y2>clearRect.bottom)
			{
				line2.point2.y=clearRect.bottom;
			}

			return true;
		}
		else
			return false;
	}
	else if (dy==0)
	{
		if (x1>x2)
		{
			ScPoint ptem=line2.point1;
			line2.point1=line2.point2;
			line2.point2=ptem;
		}

		if (y1>clearRect.top&&y1<clearRect.bottom)
		{
			if (x1<clearRect.left)
			{
				line2.point1.x=clearRect.left;
			}
			if (x2>clearRect.right)
			{
				line2.point1.y=clearRect.right;
			}

			return true;
		}
		else
			return false;
	}
	
	//求出裁剪矩形每边交点
	/*

			---------------------------------	 -
		    -								-  -
			-								- -
			-						   		+
			-							-	-
			-						-		-
			-					-			-
			-				-				-
			-			-					-
			-		-						-
			-	-							-
			+-								-
		 -	-								-
			-								-
			---------------------------------

	*/
	float k=dy/dx;
	float b=(y1+y2-k*(x1+x2))/2;
	int jdSum=0,jdx=0,jdy=0;
	ScPoint point[2],pTemp;
	//处理上边
	pTemp.y=clearRect.top;
	pTemp.x=(clearRect.top-b)/k;
	if (pTemp.x>clearRect.left&&pTemp.x<clearRect.right)
	{
		point[jdSum]=pTemp;
		jdSum++;
	}
	//处理左边
	pTemp.y=k*clearRect.left+b;
	pTemp.x=clearRect.left;
	if (pTemp.y>clearRect.top&&pTemp.y<clearRect.bottom)
	{
		point[jdSum]=pTemp;
		jdSum++;
	}
	//处理下边
	pTemp.y=clearRect.bottom;
	pTemp.x=(clearRect.bottom-b)/k;
	if (jdSum<2&&pTemp.x>clearRect.left&&pTemp.x<clearRect.right)
	{
		point[jdSum]=pTemp;
		jdSum++;
	}
	//处理右边
	pTemp.y=k*clearRect.right+b;
	pTemp.x=clearRect.right;
	if (jdSum<2&&pTemp.y>clearRect.top&&pTemp.y<clearRect.bottom)
	{
		point[jdSum]=pTemp;
		jdSum++;
	}
	//判断交点是否在线段上,在的话进行截取即用交点替换原来的断点
	if (jdSum==0)
	{
		//line2=*line;
		if (line2.point1.x<clearRect.left||line2.point2.x>clearRect.right)
		{
			return false;
		}
	}
	else if(jdSum==1)
	{
		if (point[0].x<x1||point[0].x>x2)//不在线段上
		{
			//line2=*line;
		}else
		{
			line2=*line;
			if(k<0)
				line2.point1=point[0];
			else
				line2.point2=point[0];

		}
	}
	else if(jdSum==2)
	{
		if (point[0].x>point[1].x)
		{
			temp=point[0].x;
			point[0].x=point[1].x;
			point[1].x=temp;

			temp=point[0].y;
			point[0].y=point[1].y;
			point[1].y=temp;
		}
		if (k<0)
		{
			if (point[0].x>line2.point1.x)
			{
				line2.point1=point[0];
			}
			if (point[1].x<line2.point2.x)
			{
				line2.point2=point[1];
			}
		}
		else
		{
			if (point[0].x>line2.point1.x)
			{
				line2.point1=point[0];
			}
			if (point[1].x<line2.point2.x)
			{
				line2.point2=point[1];
			}
		}
	}

	return true;
}
原文地址:https://www.cnblogs.com/gamesky/p/2665271.html