几何基础(3)
求线段交点:
前面已经讲了如何判断两条线段是否相交,现在我们来学下如何求线段的交点坐标
首先先了解下 :
定比分点公式
公式介绍
数学中常用的重要公式之一!
在直角坐标系内,已知两点A(x1,y1),B(x2,y2);在两点连线上有一点P,设它的坐标为(x,y),且向量AP比向量PB的比值为λ,那么我们说P分有向线段AB的比为λ
且P的坐标为
x=(x1 + λ · x2) / (1 + λ)
y=(y1 + λ · y2) / (1 + λ)
![](https://img-blog.csdn.net/20160906174705519?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
求得直线 AB 与直线 CD 的交点P?
![](https://img-blog.csdn.net/20160906174740819?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如此就可求出 :λ
再有公式:
x=(x1 + λ · x2) / (1 + λ)
y=(y1 + λ · y2) / (1 + λ)
求出坐标.
point jiaodian(line l1,line l2)//求交点
{
double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e)));
point p;
p.x=(l2.s.x+t*l2.e.x)/(1+t);
p.y=(l2.s.y+t*l2.e.y)/(1+t);
return p;
}
完整代码如下
:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-8;
const double PI=acos(-1.0);
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x < 0) return -1;
else return 1;
}
struct point
{
double x,y;
point(){}
point (double _x,double _y)
{
x=_x,y=_y;
}
point operator -(const point &b)const
{
return point(x-b.x,y-b.y);
}
point operator +(const point &b)const
{
return point (x+b.x,y+b.y);
}
double operator ^(const point &b)const //叉积
{
return x*b.y-y*b.x;
}
double operator *(const point &b)const //点积
{
return x*b.x+y*b.y;
}
void transxy(double B) //绕原点旋转角度B(弧度值),后的x,y
{
double tx=x,ty=y;
x= tx*cos(B) - ty*sin(B);
y= tx*sin(B) + ty*cos(B);
}
};
struct line//线
{
point s,e;
line(){}
line(point _s,point _e)
{
s=_s,e=_e;
}
};
double dist(point a,point b)//两点间距离
{
return sqrt((a-b)*(a-b));
}
bool inter(line l1,line l2)//判断线段相交
{
return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}
point jiaodian(line l1,line l2)//求交点
{
double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e)));
point p;
p.x=(l2.s.x+t*l2.e.x)/(1+t);
p.y=(l2.s.y+t*l2.e.y)/(1+t);
return p;
}
bool inter_line(line l1,line l2)//判断直线与线段是否相交
{
return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0;
}
int main()
{
double ax,ay,bx,by,cx,cy,dx,dy;
while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy)!=EOF)//分别输入两条线段的首尾端点
{
point k1(ax,ay);
point k2(bx,by);
point k3(cx,cy);
point k4(dx,dy);
line l1(k1,k2);
line l2(k3,k4);
if(inter(l1,l2))
{
printf("Yes\n");
point p;
p=jiaodian(l1,l2);
printf("%lf %lf\n",p.x,p.y);
}
else
printf("No\n");
}
// printf("%lf %lf\n",ke.x,ke.y);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)