判断线段与圆是否相交

                                             判断线段与圆是否相交

一、知识点

1、判断点是否在圆内的方法:设点到圆心的距离为d,圆的半径为r,那么有

d<r 在圆内
d=r 在圆上
d>r 在圆外

(其中d可由两点距离公式求出)

2、已知两点p1(x1,y1)、p2(x2,y2),求直线p1p2的一般式方程Ax+By+C=0

先求出两点式直线方程,然后由两点式直线方程求出一般式方程

3.点到直线的距离公式

(x,y)到直线Ax+By+C=0的距离公式为

4、余弦定理

二、判断线段与圆是否相交

情况一、两点都在圆内。不相交 

情况二、一个点在圆内,一个点在圆外。相交 

情况三、两个点都在圆外

设点p1和p2均在圆外,判断线段p1p2与圆是否相交的方法

1、求出直线p1p2的一般式方程

2、用距离公式判断圆心到直线p1p2的距离是否大于半径:距离大于半径,则不相交;距离小于等于半径,执行3

3、设圆心为o,使用余弦定理判断角op1p2和角op2p1是否都为锐角,都为锐角则相交,否则不相交。

注意:可用向量来实现余弦定理

三、C++实现

//点 
struct Point{
	double x,y;
	Point(){}
	Point(int x,int y):x(x),y(y){}
};

//圆 
struct Circle{
	double r,x,y;
	Circle(){};
	Circle(double r,double x,double y):r(r),x(x),y(y){} 
};

//判断直线p1p2与圆c是否相交,相交返回true,否则返回false 
bool judge(Point p1,Point p2,Circle c)
{
	bool flag1=(p1.x-c.x)*(p1.x-c.x)+(p1.y-c.y)*(p1.y-c.y)<=c.r*c.r;
	bool flag2=(p2.x-c.x)*(p2.x-c.x)+(p2.y-c.y)*(p2.y-c.y)<=c.r*c.r;
	if(flag1&&flag2)	//情况一、两点都在圆内 :一定不相交 
	  return false; 
	else if(flag1||flag2) //情况二、一个点在圆内,一个点在圆外:一定相交 
	  return true;
	else //情况三、两个点都在圆外 
	{
		double A,B,C,dist1,dist2,angle1,angle2;
		//将直线p1p2化为一般式:Ax+By+C=0的形式。先化为两点式,然后由两点式得出一般式 
		A=p1.y-p2.y;
		B=p2.x-p1.x;
		C=p1.x*p2.y-p2.x*p1.y;
		//使用距离公式判断圆心到直线ax+by+c=0的距离是否大于半径 
		dist1=A*c.x+B*c.y+C;
		dist1*=dist1;
		dist2=(A*A+B*B)*c.r*c.r;
		if(dist1>dist2)//圆心到直线p1p2的距离大于半径,不相交 
		  return false;
		angle1=(c.x-p1.x)*(p2.x-p1.x)+(c.y-p1.y)*(p2.y-p1.y);
		angle2=(c.x-p2.x)*(p1.x-p2.x)+(c.y-p2.y)*(p1.y-p2.y);
		if(angle1>0&&angle2>0)//余弦为正,则是锐角,一定相交 
		  return true; 
		else
		  return false; 
	} 
}

猜你喜欢

转载自blog.csdn.net/SongBai1997/article/details/86599879