线与矩形的切割算法

在球形摄像机,因为设备有水平和垂直方向以及镜头的zoom三台电机,所以画在某个空间位置上的线在设备运动之后可能会出现在视频预览中的位置变化,如下图所示:

在P215 T19 Z001的位置天花板上画一条跨界检测直线

线与矩形的切割算法_第1张图片

然后改变P的位置到203,如下图所示:

线与矩形的切割算法_第2张图片

继续转动P电机,就有可能直线的一部分转出预览界面,导致直线与矩形切割,如下图:

线与矩形的切割算法_第3张图片

这个时候传入检测库的平面坐标就需要做切割调整。

设置下左,下右,上左,上右4个点的坐标分别为(0,0)(1000,0)(0,1000)(1000,1000)

实际上就是求一条直线与这个四个点围成的矩形的交点:

因为情况太多,甚至能出现两个点都不在矩形仍然相交的情况,所以分case处理是不合理的。

既然已经抽象成一条直线,那么除了少数极其特殊的情况(垂直x或y轴),这条线都会跟这个矩形边的延长线相交。

基于以上考虑,先求出线的斜率,然后求与四条边所在线的交点,那么所有情况都可以归为对这四个交点的分类处理,是目前我能想出来的比较简单的办法,代码如下(因为代码是为公司开发的,所以此处公布的代码做了一些处理,尽量在能将逻辑表达清楚的同时不泄露公司资产):

int cut_detect_line(node_t src_point[])
{
	int i = 0;
	float x,y;
	//与四边形及四边形延长线的交点
	node_t x_axis, y_axis, x_1000, y_1000;
	
	//初始化操作
	.......
	
	//无法求斜率的单独处理
	if(src_point[0].x == src_point[1].x)
	{
		......
	}
	else
	{
		//计算y = kx + b的k和b
		float k = (src_point[0].y - src_point[1].y)/(src_point[0].x - src_point[1].x);
		float b = src_point[0].y - src_point[0].x * k;

		
		//计算x_axis, y_axis, x_1000, y_1000四个点的坐标
		

		for(i = 0; i < 2; ++i)
		{
			x = src_point[i].x;
			y = src_point[i].y;
			
			//跟x轴交点,如果y在外面,处理y
			if(x_axis.x >= 0 && x_axis.y <= 999)
			{
				if(y < 0)
				{
					.......
				}
			}

			if(y_axis.y >= 0 && y_axis.y <= 999)
			{
				if(x < 0)
				{
					.......
				}
			}
				
			if(y_1000.x >= 0 && y_1000.x <= 999)
			{
				if(y > 999)
				{
					.......
				}
			}

			if(x_1000.y >= 0 && x_1000.y <= 999)
			{
				if(x > 999)
				{
					.......
				}
			}
			//赋给入参
		}
	}
	
	return 0;
}




你可能感兴趣的:(algorithms)