计算点到线段的距离、多边形切割、线段交点、矢量角度

旧代码,几何相关
开源代码gpc含有多边形切割算法。

double CalDis(const double x1, const double y1,
		const double x2, const double y2)
	{
		return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
	}	
double CalDis(const double ptx, const double pty,
						  const double x1, const double y1,
						  const double x2, const double y2)
{
	double f = (x2-x1)*(ptx-x1) + (y2-y1)*(pty-y1);
	if (f<=0)
		return CalDis(ptx, pty, x1, y1);
	double d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
	if (f>d)			
		return CalDis(ptx, pty, x2, y2);		
	f = f/d;		
	double projX = (x1 + (x2 - x1)*f);		
	double projY = (y1 + (y2 - y1)*f);		
	return CalDis(ptx, pty, projX, projY);		
}

线段交点


//--------------------------------------------------------------------------------
//Function:
//get the point of two lines
//Parameters:
//       leftPoint   [in]: the start point of first line
//       rightPoint  [in]: the end point of first line
//       point1      [in]:the start point of second line
//       point2      [in]: the end point of second line
//       point       [out]:the cross point
//Return:
//      two lines have cross point whether or not
//-------------------------------------------------------------------------------
bool LineOperate::GetCrossPoint(const POINT &leftpoint,const POINT &rightpoint,
								const POINT &point1,const POINT &point2,
								POINT &point)
{
	if (leftpoint.x == rightpoint.x)//clip by x line
	{
		if (point1.x == point2.x)//平行线不切割
		{
			return(false);
		}
		else if (leftpoint.x == point1.x)//首点落在切割线上
		{
			point.x = point1.x;
			point.y = point1.y;
			return(true);
		}
		else if (leftpoint.x == point2.x)//尾点落在切割线上
		{
			point.x = point2.x;
			point.y = point2.y;
			return(true);
		}
		else if (leftpoint.x > point1.x && leftpoint.x > point2.x)//不相交
		{
			return(false);
		}
		else if (leftpoint.x < point1.x && leftpoint.x < point2.x)//不相交
		{	
			return(false);
		}
		else
		{
			double x = static_cast<double>(leftpoint.x);
			double y = point1.y + 
				static_cast<double>(x - point1.x) 
				/ static_cast<double>(point2.x-point1.x)
				* static_cast<double>(point2.y - point1.y) ;
			point.x = static_cast<int>(x);
			point.y = static_cast<int>(y);
			return(true);
		}
		
	}

	if (leftpoint.y == rightpoint.y)//clip by y line
	{
		if (point1.y == point2.y)//平行线不切割
		{
			return(false);
		}
		else if (leftpoint.y == point1.y)//首点落在切割线上
		{
			point.x = point1.x;
			point.y = point1.y;
			return(true);
		}
		else if (leftpoint.y == point2.y)//尾点落在切割线上
		{
			point.x = point2.x;
			point.y = point2.y;
			return(true);
		}
		else if (leftpoint.y > point1.y && leftpoint.y > point2.y)//不相交
		{
			return(false);
		}
		else if (leftpoint.y < point1.y && leftpoint.y < point2.y)//不相交
		{		
			return(false);
		}
		else
		{
			double y = static_cast<double>(leftpoint.y);
			double x = point1.x + 
				static_cast<double>(y - point1.y) 
				/ static_cast<double>(point2.y - point1.y)
				* static_cast<double>(point2.x - point1.x) ;
			point.x = static_cast<int>(x);
			point.y = static_cast<int>(y);
			return(true);
		}		
	}
	return(false);
}

线段切割


//-----------------------------------------------------------------------------------------
//Function:
//clip line arithmetic
//Parameters:
//       input_point_vec	   [in]: the vector of points of the clipped line
//       start_point            [in]: the start point of the clipping line
//       end_pointt            [in]:the end point of the clipping line
//       n                 [out]: the number of new NODE
//Return:
//      None
//-----------------------------------------------------------------------------------------
void LineOperate::ClipLineByLine(POINT_VEC& input_point_vec, const POINT& start_point, 
								 const POINT& end_point)
{	
	POINT temp_point;
	NODE_CLIP_POINT crossPoint; 
	if (COORD_MIN_NUM > input_point_vec.size())
	{
		throw BbException(NORMAL_ERR, _T("mif_road coord num error"));
	}
	else
	{
		for (POINT_VEC::iterator it_point = input_point_vec.begin(); 
			it_point + 1 != input_point_vec.end(); it_point++)
		{ 
			POINT	 current_point;
			POINT	 next_point;
			current_point.x = (*it_point).x;
			current_point.y = (*it_point).y;
			next_point.x = (*(it_point + 1)).x;
			next_point.y = (*(it_point + 1)).y;
			//if the line and the clipline have crosspoint
			if (TRUE == GetCrossPoint(start_point, end_point, current_point, next_point, temp_point))
			{
				//if cross point is the start point of the current line 
				if (temp_point.x == static_cast<LONG>(current_point.x) && 
					temp_point.y == static_cast<LONG>(current_point.y))
				{
					(*it_point).node_type = NODEPOINT;//set the NODE flag for this point
					//if cross point is not the first point of the clipped line
				/*	if (it_point != input_point_vec.begin())
					{
						n++;
					}		*/	
				}
				//if cross point is the end point of the current line, no deal
				else if (temp_point.x == static_cast<long>(next_point.x) && temp_point.y == static_cast<long>(next_point.y))
				{
				}
				//other cases,set the NODE flag for the crosspoint and
				//insert the crosspoint into the clipped line at the next position of current point
				else
				{
					crossPoint.x = temp_point.x;
					crossPoint.y = temp_point.y;
					crossPoint.node_type = NODEPOINT;
					it_point = input_point_vec.insert(it_point + 1, crossPoint);
					//n++;
				}	
			}
		}
	}
	return;
}

矢量角度


//------------------------------------------------------------------------------------------
//Function:
//get the distance of one point to the line 
//Parameters:
//       start_point         [in]: the start point of the  line
//       end_point           [in]: the end point of the line
//Return:
//      2点矢量方向(起始点指向终点)与水平方向的夹角(0度~360度)
//------------------------------------------------------------------------------------------
double LineOperate::GetTwoPointVectorAngle(POINT start_point, POINT end_point)
{
	if (start_point.x == end_point.x)
	{
		if (start_point.y < end_point.y)//垂直情况(起始点在下,终点在上)
		{
			return(PI / 2);
		}
		else if (start_point.y > end_point.y)//垂直情况(起始点在上,终点在下)
		{ 
			return(3* PI / 2);
		}
		else//同一个点情况
		{
			return(0);
		}		
	}

	else if (start_point.y == end_point.y)
	{
		if (start_point.y < end_point.y)//水平情况(起始点在左,终点在右)
		{
			return(0);
		} 
		else if (start_point.y > end_point.y)//水平情况(起始点在右,终点在左)
		{
			return(PI);
		}
		else//同一个点情况
		{
			return(0);
		}
	}

	else if ((start_point.x < end_point.x) && (start_point.y < end_point.y))//角度第一象限情况(起始点在下,终点在上)
	{
		return(atan(static_cast<double>(end_point.y - start_point.y) / 
			static_cast<double>(end_point.x - start_point.x)));
	}

	else if ((start_point.x > end_point.x) && (start_point.y < end_point.y))//角度第二象限情况(起始点在下,终点在上)
	{
		return(PI - atan(static_cast<double>(end_point.y - start_point.y) / 
			static_cast<double>(start_point.x - end_point.x)));
	}

	else if ((start_point.x > end_point.x) && (start_point.y > end_point.y))//角度第三象限情况(起始点在上,终点在下)
	{
		return(PI + atan(static_cast<double>(start_point.y - end_point.y) / 
			static_cast<double>(start_point.x - end_point.x)));
	}

	else if ((start_point.x < end_point.x) && (start_point.y > end_point.y))//角度第四象限情况(起始点在上,终点在下)
	{
		return (2* PI - atan(static_cast<double>(start_point.y - end_point.y) / 
			static_cast<double>(end_point.x - start_point.x)));
	}
	else
	{
		CSERROR("求2点角度异常");
		return(0);
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值