题目:http://poj.org/problem?id=1269
题意:给出两条直线(4个点),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。
分析:先判断是否共线,否则判断是否平行,否则只能相交,求出交点。
所用到的公式:
1、已知(x1,y1),求ax+by+c=0;
a=y2-y1;b=x1-x2;c=y1 * x2 - x1 * y2;
2、已知(x0,y0),求关于ax+by+c=0的对称点(x1,y1);
k=-2*(a*x0+b*y0+c)/(a*a+b*b);
x1=x0+k*a;
y1=y0+k*b;
3、已知a1x+b1y+c1=0,a2x+b2y+c2=0,求交点(x1,y1);
x1=(c2*b1-c1*b2)/(a1*b2-a2*b1);
y1=(-a1*x1-c1)/b1;
<span style="font-size:12px;"> //直线AB与直线CD的关系,如果相交就输出交点坐标
void Solve(Point A,Point B,Point C,Point D)
{
if(fabs(cross(A,B,C))<=EPS&&fabs(cross(A,B,D))<=EPS) puts("LINE"); //共线
else if((B.x-A.x)*(D.y-C.y)==(D.x-C.x)*(B.y-A.y)) puts("NONE"); //平行
else //相交
{
double a1=A.y-B.y;
double b1=B.x-A.x;
double c1=A.x*B.y-B.x*A.y;
double a2=C.y-D.y;
double b2=D.x-C.x;
double c2=C.x*D.y-D.x*C.y;
double x=(b1*c2-b2*c1)/(a1*b2-a2*b1);
double y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
printf("%.2lf %.2lf\n",x,y);
}
} </span>
AC代码:
<span style="font-size:12px;">#include <cstdio>
#include <cmath>
#include <iostream>
#define exp 1e-10 //两个向量的叉积等于0,说明两向量共线;(通过一元函数证明);
using namespace std;
struct Point
{
double x1,x2,y1,y2;
}A,B;
double cross(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
void check(Point a, Point b)
{
double c[4];
c[0] = cross(a.x2 - a.x1, a.y2 - a.y1, b.x1 - a.x1, b.y1 - a.y1);
c[1] = cross(a.x2 - a.x1, a.y2 - a.y1, b.x2 - a.x1, b.y2 - a.y1);
// c[2] = cross(b.x2 - b.x1, b.y2 - b.y1, a.x1 - b.x1, a.y1 - b.y1);
// c[3] = cross(b.x2 - b.x1, b.y2 - b.y1, a.x2 - b.x1, a.y2 - b.y1);
if(fabs(c[0])<= exp && fabs(c[1])<= exp) puts("LINE"); //两向量的叉积为0,则共线;
else if( (a.x1 - a.x2) * (b.y1 - b.y2) == (a.y1 - a.y2) * (b.x1 - b.x2) ) puts("NONE"); //平行,斜率相等,不共线肯定平行;
else //求交点(计算几何公式)
{
double a1 = a.y2 - a.y1;
double b1 = a.x1 - a.x2;
double c1 = a.y1 * a.x2 - a.x1 * a.y2;
double a2 = b.y2 - b.y1;
double b2 = b.x1 - b.x2;
double c2 = b.y1 * b.x2 - b.x1 * b.y2;
double x = (b1 * c2 - b2 * c1) / (a1 * b2 - b1 * a2);
double y = (a2 * c1 - a1 * c2) / (a1 * b2 - b1 * a2);
printf("POINT %.2lf %.2lf\n",x,y);
}
}
int main()
{
int n;
// freopen("in.txt","r",stdin);
scanf("%d",&n);
puts("INTERSECTING LINES OUTPUT");
while(n--)
{
scanf("%lf %lf %lf %lf",&A.x1,&A.y1,&A.x2,&A.y2);
scanf("%lf %lf %lf %lf",&B.x1,&B.y1,&B.x2,&B.y2);
check(A,B);
}
puts("END OF OUTPUT");
return 0;
}</span>