解析几何--交点的计算

这个专题讨论用解析几何的方法解决线段,直线和点的计算问题。

默认使用笛卡尔直角坐标系。

计算点到线段的最近点。

已知线段P1P2((x1,y1),(x2,y2)),点Q(x0,y0),求点Q到线段P1P2的 最近坐标。

存在两种情况:

1.情况一:y1=y2&&x1!=x2时,直线P1P2的方程为y=y1,则Q到P1P2的垂线方程为x=x0,垂足坐标为(x0,y1)。

直线AB,下面是Q的三种不同的位置。最近的点的坐标很明显分别对应的三个红色的点。

同理x1=x2时:

直线AB,左右时Q的三种不同的位置。最近点的坐标对应的三个红点。

2.情况二:当y1=y2&&x1=x2时,该线段不平行于x轴&&不平行于y轴,斜率存在但不为0,则可设线段的两端点分别为P1,P2,斜率k=(y2-y1)/(x2-x1)。

该直线方程为:y=k(x-x1)+y1;

垂线方程为y=(-1/k)(x-x0)+y0;连立公式,解得x=(x1*k^2+k(y0-y1)+x0)/(1+k^2);y=k(x-x1)+y1;

同理可以求出点到折线,矩形,多边形的最近点。

 

计算点到圆的最近距离及最近点的坐标。

已知圆心坐标O=(xr,yr)及半径r,点P=(x0,y0),求点P到最近点的坐标分为以下几种情况:

1. P=A,则点到圆的最近距离为r,点位圆上任意一点的坐标。

2. P=C||P=C',y轴相等,则为:(xr+r,yr) || (x-r,yr)。

3. P=D||P=D',x轴相等,则为:(xr,yr+r) || (xr,yr-r)。

4. P=G||P=G',没有什么关系,存在一个斜率不为0的直线,则斜率为:k=(y0-yr)/(x0-xr)。

直线AG的方程为:y=k(x-Gx)+Gy。圆的方程为:(x-Ax)^2+(y-Ay)^2=r^2;连立求出交点(注意有两个)即可。

 

计算两条共线的线段的交点。

对于两条共线的线段,位置关系有以下几种情况:

分别是,没交点,有一个,无穷,无穷。

计算线段与线段的交点。

虽然感觉不太实用,但是姑且还是写出来吧,向量大法好!

首先判断两线段是否相交,

一般情况:k1=(y2-y1)/(x2-x1),k2=(y4-y3)/(x4-x3);

直线方程分别是:L1:y=k1(x-x1)+y1   L2:y=k2(x-x3)+y3;

注意斜率为0及斜率不存在的特判。

计算线段||直线和圆的交点。

参考上文:”点到圆的最近距离“求解。

求圆和圆的交点

用三角函数求交点,精度更高哦。

Code:

int Dcmp(double x){if(fabs(x)<EPS) return 0;return x<0?-1:1;}
struct Point{
	double x,y;
	Point(double _x=0,double _y=0){
		x=_x;y=_y;
	}
	friend Point operator - (Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
	friend double operator * (Point a,Point b){return a.x*b.x+a.y*b.y;}
	friend double operator ^ (Point a,Point b){return a.x*b.y-a.y*b.x;}
	friend int operator == (Point a,Point b){return Dcmp(a.x-b.x)==0&&Dcmp(a.y-b.y)==0;}
};
struct Cir{
	Point cen;double r;
	void InPut(){scanf("%lf%lf%lf",&cen.x,&cen.y,&r);}
	Point Inter(double a){return Point(cen.x+cos(a)*r,cen.y+sin(a)*r);}
};
double Distance(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
double Distance(Point a){return sqrt(a.x*a.x+a.y*a.y);}

double Ang(Point a){
	return atan2(a.y,a.x);
}
int CirCir(Cir c1,Cir c2,Point &p1,Point &p2){
	double d=Distance(c1.cen,c2.cen);
	if(Dcmp(d)==0){
		if(Dcmp(c1.r-c2.r)==0) return -1;
		return 0;
	}
	if(Dcmp(c1.r+c2.r-d)<0) return 0;
	if(Dcmp(fabs(c1.r-c2.r)-d)>0) return 0;
	double a=Ang(c2.cen-c1.cen);
	double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2.0*d*c1.r));
	p1=c1.Inter(a-da);p2=c1.Inter(a+da);//所求得的两交点 
	if(p1==p2) return 1;
	return 2;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值