判断直线是否相交,貌似很容易,直接用一个向量叉乘公式:x1*y2-x2*y1.如果结果为0,则直线是平行或者重合,否则必然相交...
但如何判断两条线段是否相交呢?我们给出了两条线段的四个端点,这两条条线段必须跨过另一条线段则必然相交,所以只需要算出两个端点分别在一条线段的两侧就OK了,至于怎么算是否在端点两侧还是用到上面的叉乘公式,两个端点的结果的积为负数,则在两侧,当然这里有种特殊情况需要处理,就是叉乘等于零,也就是端点在线段的延伸线上,所以这里需要判断这个端点是否在另一条线段上就OK了...这个代码没有注释,给以后的我自己看的...
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct point
{
int x;
int y;
}p[5];
int fff(point a,point b,point c)
{
point p1,p2;
p1.x=a.x-c.x;
p1.y=a.y-c.y;
p2.x=b.x-c.x;
p2.y=b.y-c.y;
return (p1.x*p2.y-p1.y*p2.x);
}
int ffff(point a,point b,point c)
{
point min,max;
min.x=b.x;min.y=b.y;max.x=a.x;max.y=a.y;
if (a.x<b.x)
{
min.x=a.x;
max.x=b.x;
}
if (a.y<b.y)
{
min.y=a.y;
max.y=b.y;
}
if (c.x>=min.x && c.x<=max.x && c.y>=min.y && c.y<=max.y) return 1;
else return 0;
}
int ff(point a,point b,point c,point d)
{
int q,w,e,r;
q=fff(a,b,c);
w=fff(a,b,d);
e=fff(c,d,a);
r=fff(c,d,b);
if (q*w<0 && e*r<0)
return 1;
else
{
if (q==0 && ffff(a,b,c)) return 1;
if (w==0 && ffff(a,b,d)) return 1;
if (e==0 && ffff(c,d,a)) return 1;
if (r==0 && ffff(c,d,b)) return 1;
}
return 0;
}
int main()
{
while (~scanf("%d%d%d%d%d%d%d%d",&p[0].x,&p[0].y,&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y))
{
if (ff(p[0],p[1],p[2],p[3])) printf("相交\n");
else printf("不相交\n");
}
return 0;
}
求交点的公式:
void jiaodian()
{
double t=(double)((p[0].x-p[2].x) * (p[2].y-p[3].y)-(p[0].y-p[2].y)*(p[2].x-p[3].x))
/(double)((p[0].x-p[1].x) * (p[2].y-p[3].y)-(p[0].y-p[1].y)*(p[2].x-p[3].x));
q.x=(p[1].x-p[0].x)*t;
q.y=(p[1].y-p[0].y)*t;
printf("交点为:(%lf,%lf)\n",q.x,q.y);
}
补充:上面求交点的公式貌似不对。我也不记得以前怎么搞到这个公式。还自认为对了。补充真正的公式和解法:http://blog.csdn.net/modiz/article/details/24418795
顺便粘上完整的代码。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
using namespace std;
//#define DEBUG
struct node
{
double x,y;
node (){}
node (double a,double b):x(a),y(b){
}
}p[5];
double js(node p1,node p2,node p3)
{
node h1,h2;
h1.x=p3.x-p1.x;
h1.y=p3.y-p1.y;
h2.x=p2.x-p1.x;
h2.y=p2.y-p1.y;
return (h1.x*h2.y-h1.y*h2.x);
}
int pd1(node p1,node p2,node p3)
{
double t;
if (p1.x>p2.x)
{
t=p1.x;
p1.x=p2.x;
p2.x=t;
}
if (p1.y>p2.y)
{
t=p1.y;
p1.y=p2.y;
p2.y=t;
}
if (p3.x>=p1.x && p3.x<=p2.x && p3.y>=p1.y && p3.y<=p2.y)
return 1;
else return 0;
}
int pd(node p1,node p2,node p3,node p4)
{
double d1,d2,d3,d4;
d1=js(p3,p4,p1);
d2=js(p3,p4,p2);
d3=js(p1,p2,p3);
d4=js(p1,p2,p4);
if (d1*d2<0 && d3*d4<0)
return 1;
else
{
if (d1==0 && pd1(p3,p4,p1)) return 1;
if (d2==0 && pd1(p3,p4,p1)) return 1;
if (d3==0 && pd1(p1,p2,p3)) return 1;
if (d4==0 && pd1(p1,p2,p4)) return 1;
}
return 0;
}
node operator -(node a,node b)
{
return node(a.x-b.x,a.y-b.y);
}
double cross(node a,node b)
{
return (a.x*b.y)-(a.y*b.x);
}
void getp(node a,node b,node c,node d)
{
node pp;
pp.x=(c.x*cross(b-a,d-a)-d.x*cross(b-a,c-a))/((cross(b-a,d-a)-cross(b-a,c-a)));
pp.y=(c.y*cross(b-a,d-a)-d.y*cross(b-a,c-a))/((cross(b-a,d-a)-cross(b-a,c-a)));
printf("交点为:(%lf,%lf)\n",pp.x,pp.y);
return;
}
int main()
{
while (~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y,&p[4].x,&p[4].y))
{
if (pd(p[1],p[2],p[3],p[4]))
{
/*double t=(double)((p[1].x-p[3].x) * (p[3].y-p[4].y)-(p[1].y-p[3].y)*(p[3].x-p[4].x))
/(double)((p[1].x-p[2].x) * (p[3].y-p[4].y)-(p[1].y-p[2].y)*(p[3].x-p[4].x));
node q;
q.x=(p[2].x-p[1].x)*t;
q.y=(p[2].y-p[1].y)*t;
printf("交点为:(%lf,%lf)\n",q.x,q.y);
double lll=js(p[1],p[2],p[4]);
cout<<lll<<endl;
double k1=fabs(js(p[1],p[2],p[3])/js(p[1],p[2],p[4]));
printf("交点为:(%lf,%lf)\n",(p[3].x+k1*p[4].x)/(1+k1),(p[3].y+k1*p[4].y)/(1+k1));*/
getp(p[1],p[2],p[3],p[4]);
}
else printf("No\n");
}
return 0;
}