http://poj.org/problem?id=1269
这道题目我搞了好久啊,先是拿到题的时候不知道应该如何去判断两条直线是否相交,然后是怎么判断共线、平行、交点等等一大堆东西。然后我就去网上找解释,果然找到
了,用叉积做的。突然觉得叉积好强大,后悔当时高等代数没学好啊。。。。。。。。
下面这个人的分析写的挺详细的,我的思路基本就是按照他的分析进行的。
http://zxj015.blog.163.com/blog/static/17061373020113265341773/
1、先是判断两直线是否共线
可以利用叉积判断三点共线的方法,判断构成两直线的四个点是否共线,四个点都要判断,以免出现特殊情况。
2、判断两直线是否平行
若直线A(a,b)与直线B(c,d)平行,则a/c==b/d;
3、利用叉积求相交直线的交点
假设交点为P(x0,y0),可以利用交点和两条直线的两个端点共线的性质列出方程组进行求解。
这里就不再赘述。
代码如下:
/*解题思路:
1、判断是否共线:运用叉积,叉积为0,则共线
2、判断是否平行
A(a,b)
B(c,d)
若向量A与向量B共线,则a/c=b/d
3、求交点
若交点为p0(x0,y0),则有
(p1-p0)X(p2-p0)=0
(p3-p0)X(p4-p0)=0
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1e-8
const int maxn=12;
struct point
{
double x,y;
};
point a,b,c,d;
double min(double a, double b) { return a < b ? a : b;}
double max(double a, double b) { return a > b ? a : b;}
//判断直线ab是否和直线cd共线
bool inter(point a,point b,point c)
{
//叉积abxbc==0
if((b.x-a.x)*(c.y-b.y)-(c.x-b.x)*(b.y-a.y)==0) return 0;
return 1;
}
//a/c==b/d
bool nointer(point a,point b,point c,point d)
{
if((b.x-a.x)*(d.y-c.y)-(d.x-c.x)*(b.y-a.y)==0)
return 1;
return 0;
}
//求两相交直线ab和cd的交点
void interpoint(point a,point b,point c,point d)
{
double a1,b1,c1,a2,b2,c2;
a1=a.y-b.y;
b1=b.x-a.x;
c1=a.x*b.y-a.y*b.x;
a2=c.y-d.y;
b2=d.x-c.x;
c2=c.x*d.y-c.y*d.x;
double x=(c1*b2-c2*b1)/(a2*b1-a1*b2);
double y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
printf("%.2lf %.2lf\n",x,y);
}
int main()
{
int n;
scanf("%d",&n);
printf("INTERSECTING LINES OUTPUT\n");
while(n--)
{
cin>>a.x>>a.y>>b.x>>b.y;
cin>>c.x>>c.y>>d.x>>d.y;
if(!inter(a,b,c)&&!inter(a,b,d)){printf("LINE\n");continue;}
if(nointer(a,b,c,d)){printf("NONE\n");continue;}
printf("POINT ");
interpoint(a,b,c,d);
}
printf("END OF OUTPUT\n");
return 0;
}