题意:给出两条直线,判断这两条直线的关系,即问是否相交,如果相交求出交点,如果不相交,那么他们是相离还是重合?
分析:首先去判断直线P1P2和Q1Q2和是否平行,判断直线平行可以利用叉乘。
如果(P2-P1)×(Q2-Q1)== 0的话,那么两直线平行;
得到直线平行,就要看是否重合了。
判断重合就相当于判断一条直线上的点是否存在于另一条直线上,假设这里我们看P1是否在Q1Q2上。
如果(Q1-P1)×(Q2-P1)== 0,说明重合。
反之,如果(Q1-P1)×(Q2-P1)!= 0,说明相离。
那么如果(P2-P1)×(Q2-Q1)!= 0的话,两直线一定相交,要求出交点.
求交点的方法http://blog.csdn.net/dgq8211/article/details/7952825
参考代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define eps 1e-8
int n;
int sgn( double x)
{
if( fabs(x) < eps)
return 0;
if( x < 0)
return -1;
return 1;
}
struct Point{
double x,y;
Point(){}
Point( double xx, double yy)
{
x = xx;
y = yy;
}
Point operator - ( const Point &p)const
{
return Point(x-p.x,y-p.y);
}
double operator * ( const Point &p)const
{
return x*p.x+y*p.y;
}
double operator ^ ( const Point &p)const
{
return x*p.y-p.x*y;
}
};
struct Line{
Point s,e;
Line(){}
Line( Point ss, Point ee)
{
s = ss;
e = ee;
}
//判断两条直线之间的关系
pair<Point,int> operator &( const Line &p)const
{
Point res = s;
if( sgn((s-e)^(p.s-p.e)) == 0)//两条直线平行
{
if( sgn((p.s-s)^(p.e-s)) == 0)//点s在线段p上
return make_pair(res,0);//两直线重合
return make_pair(res,1);//两直线平行
}
double t = ((s-p.s)^(p.s-p.e))/((s-e)^(p.s-p.e));
// cout<<res.x<<" "<<res.y<<" "<<t<<endl;
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(res,2);//有交点
}
};
Line l1,l2;
//计算p2p1×p3p1
int xmult( Point p1, Point p2, Point p3)
{
return (p2-p1)^(p3-p1);
}
//判断两条线段是否相交
/*
int SegInterLine( Line l1, Line l2)
{
//快速排斥实验
if( min(l1.s.x,l1.e.x) <= max(l2.s.x,l2.e.x) && min(l2.s.x,l2.e.x) <= max(l1.s.x,l1.e.x) && min(l1.s.y,l1.e.y) <= max(l2.s.y,l2.e.y) && min(l2.s.y,l2.e.y)<= max(l1.s.y,l1.e.y))
{
//快速排斥实验得到可能相交
//跨立实验
if( xmult(l1.s,l2.s,l1.e)*xmult(l1.s,l1.e,l2.e) <= 0 && xmult(l2.s,l1.e,l2.s)*xmult(l2.s,l2.e,l1.e) <= 0)
return true;
}
return false;
}
*/
int main()
{
int T;
scanf("%d",&T);
puts("INTERSECTING LINES OUTPUT");
while( T--)
{
double x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
l1 = Line(Point(x1,y1),Point(x2,y2));
l2 = Line(Point(x3,y3),Point(x4,y4));
// int check = SegInterLine(l1,l2);
pair<Point,int> ans = l1&l2;
if( ans.second == 2)
printf("POINT %.2f %.2f\n",ans.first.x,ans.first.y);
else if( ans.second == 1)
puts("NONE");
else if( ans.second == 0)
puts("LINE");
}
puts("END OF OUTPUT");
return 0;
}