Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 13009 | Accepted: 5774 |
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
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(p4-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 <cmath> #include <cstdio> const double T = 1e-8; struct Node{ double x, y; }p1, p2, p3, p4; double ChaJi(Node a, Node b, Node c){ return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); } void Solve(){ if(ChaJi(p1, p2, p3) == 0 && ChaJi(p1, p2, p4) == 0) //共线; puts("LINE"); else if((p1.x-p2.x)*(p3.y-p4.y) == (p1.y-p2.y)*(p3.x-p4.x)) // 平行 puts("NONE"); else{ //相交 double a1 = p1.y-p2.y; double b1 = p2.x-p1.x; double c1 = p1.x*p2.y-p2.x*p1.y; double a2 = p3.y-p4.y; double b2 = p4.x-p3.x; double c2 =p3.x*p4.y-p4.x*p3.y; double x = (c1*b2-c2*b1)/(a2*b1-a1*b2); double y = (a2*c1-a1*c2)/(a1*b2-a2*b1); printf("POINT %.2f %.2f\n", x, y); } } int main(){ int n; while(scanf("%d", &n) != EOF){ printf("INTERSECTING LINES OUTPUT\n"); while(n--){ scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &p1.x, &p1.y, &p2.x, &p2.y, &p3.x, &p3.y, &p4.x, &p4.y); Solve(); } printf("END OF OUTPUT\n"); } return 0; }