Description
Your program will repeatedly read in four points that define two lines in the x-y plane and determine how and where the lines intersect. All numbers required by this problem will be reasonable, say between -1000 and 1000.
Input
Output
Sample Input
5 0 0 4 4 0 4 4 0 5 0 7 6 1 0 2 3 5 0 7 6 3 -6 4 -3 2 0 2 27 1 5 18 5 0 3 4 0 1 2 2 5
Sample Output
INTERSECTING LINES OUTPUT POINT 2.00 2.00 NONE LINE POINT 2.00 5.00 POINT 1.07 2.20 END OF OUTPUT
Hint
Source
解题思路
先判断两条直线是不是同线,不是的话再判断是否平行,再不是的话就只能是相交的,求出交点。
如何判断是否同线?由叉积的原理知道如果p1,p2,p3共线的话那么(p2-p1)X(p3-p1)=0。因此如果p1,p2,p3共线,p1,p2,p4共线,那么两条直线共线。direction()求叉积,叉积为0说明共线。
如何判断是否平行?由向量可以判断出两直线是否平行。如果两直线平行,那么向量p1p2、p3p4也是平等的。即((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x))==0说明向量平等。
如何求出交点?这里也用到叉积的原理。假设交点为p0(x0,y0)。则有:
(p1-p0)X(p2-p0)=0
(p3-p0)X(p2-p0)=0
展开后即是
(y1-y2)x0+(x2-x1)y0+x1y2-x2y1=0
(y3-y4)x0+(x4-x3)y0+x3y4-x4y3=0
将x0,y0作为变量求解二元一次方程组。
假设有二元一次方程组
a1x+b1y+c1=0;
a2x+b2y+c2=0
那么
x=(c1*b2-c2*b1)/(a2*b1-a1*b2);
y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
因为此处两直线不会平行,所以分母不会为0。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define eps 1e-8
struct point
{
double x,y;
};
struct line
{
point sp,ep;
};
double x_multi(point p1,point p2,point p3)
{
return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}
bool Parallel(line a,line b) //平行
{
if((a.sp.x-a.ep.x)*(b.sp.y-b.ep.y)-(b.sp.x-b.ep.x)*(a.sp.y-a.ep.y)==0.0)
return true;
return false;
}
/*point Interpoint(line u,line v) //求两相交直线交点
{
point ret=u.sp;
double t=((u.sp.x-v.sp.x)*(v.sp.y-v.ep.y)-(u.sp.y-v.sp.y)*(v.sp.x-v.ep.x))/
((u.sp.x-u.ep.x)*(v.sp.y-v.ep.y)-(u.sp.y-u.ep.y)*(v.sp.x-v.ep.x));
ret.x+=(u.ep.x-u.sp.x)*t;
ret.y+=(u.ep.y-u.sp.y)*t;
return ret;
}*/
point Interpoint(line a,line b) //求两相交直线交点,此方法精度更高
{
point ret;
double u=x_multi(a.sp,a.ep,b.sp),v=x_multi(a.ep,a.sp,b.ep);
ret.x=(b.sp.x*v+b.ep.x*u)/(u+v);
ret.y=(b.sp.y*v+b.ep.y*u)/(u+v);
return ret;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
puts("INTERSECTING LINES OUTPUT");
line a,b;
while(n--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.sp.x,&a.sp.y,&a.ep.x,&a.ep.y,&b.sp.x,&b.sp.y,&b.ep.x,&b.ep.y);
if(Parallel(a,b))
{
if(x_multi(a.sp,a.ep,b.sp)==0.0)
puts("LINE");
else
puts("NONE");
}
else
{
point ans=Interpoint(a,b);
printf("POINT %.2lf %.2lf\n",ans.x,ans.y);
}
}
puts("END OF OUTPUT");
}
return 0;
}
本文介绍了一种通过代数方法来确定平面上两条直线如何相交的算法,包括判断直线是否平行、共线以及计算交点坐标。适用于解决计算机图形学及几何问题。
595

被折叠的 条评论
为什么被折叠?



