链接:http://poj.org/problem?id=1269
题意:给两条直线,判断它们是重合、平行还是相交,相交则求交点。
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> using namespace std; const double eps=1e-8; struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {} } p[4]; typedef Point Vector; Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); } Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); } double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; } Point LineIntersection(Point P,Vector v,Point Q,Vector w)//两条直线求交点 { Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } int main() { int n; Point p0; double t; cin>>n; cout<<"INTERSECTING LINES OUTPUT"<<endl; while(n--) { for(int i=0; i<4; ++i) cin>>p[i].x>>p[i].y; Vector v1(p[1]-p[0]),v2(p[3]-p[2]); if(fabs(Cross(v1,v2))<eps)//共线 { // t=(p[2].x-p[0].x)/v1.x;//v1.x为0,就错了 // if(fabs(p[2].y-p[0].y-t*v1.y)<eps) t=(p[2].x-p[0].x); if(fabs(v1.x*(p[2].y-p[0].y)-t*v1.y)<eps) cout<<"LINE"<<endl; else cout<<"NONE"<<endl; } else//相交 { p0=LineIntersection(p[0],v1,p[2],v2); cout<<"POINT "; printf("%.2lf %.2lf\n",p0.x,p0.y); } } cout<<"END OF OUTPUT"<<endl; return 0; }
这里判断两直线重合是用的参数方程,但是一开始没有考虑到v1.x为0的情况,必然过不了,然后改成现在这样。
也可以用叉积来判断是否重合。
p2与p0和p1共线,且p3与p0和p1共线。
if(fabs(Cross(v1,p[2]-p[0]))<eps && fabs(Cross(v1,p[3]-p[0]))<eps)//重合 cout<<"LINE"<<endl; else if(fabs(Cross(v1,v2))<eps)//平行 cout<<"NONE"<<endl;
或者是用直线的一般式:ax+by+c=0 利用相似来判读
平行则有:a1/a2=b1/b2
重合有:a1/a2=b1/b2=c1/c2
高中的几何知识真是忘得差不多了啊。。。。泪。。。
究竟是我抛弃了历史,还是历史遗弃了我。