总结用点积和叉积求解直线各类模板:
#include<iostream>
#include<math.h>
using namespace std;
#define precision 0.000001
struct point
{
double x,y;
};
//a^b=-2==>axb<0或axb=-1,消除浮点误差
int dblcmp(double d)
{
if(fabs(d)<precision)
return 0;
return (d>0)?1:-1;
}
//叉积运算
double cc(double a,double b,double c,double d)
{
return a*c-b*d;
}
double cross(point p1,point p2,point p3)
{
return cc(p2.x-p1.x,p2.y-p1.y,p3.x-p1.x,p3.y-p1.y);
}
//求点积
double d(double a,double b,double c,double d)
{
return a*c+b*d;
}
double dd(point a,point b,point c)
{
return d(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}
//判断点a是否在bc范围内
int betweenCmp(point a,point b,point c)
{
return dblcmp(dd(a,b,c));
}
//叉积求交点
int segcross(point a,point b,point c,point d,point &p)
{
double s1,s2,s3,s4;
int d1,d2,d3,d4;
d1=dblcmp(s1=cross(a,b,c));
d2=dblcmp(s2=cross(a,b,d));
d3=dblcmp(s3=cross(c,d,a));
d4=dblcmp(s4=cross(c,d,b));
//规范性相交求交点
if((d1^d2==-2)&&(d3^d4)==-2)
{
p.x=(s2*c.x-s1*d.x)/(s2-s1);
p.y=(s2*c.y-s1*d.y)/(s2-s1);
return 1;
}
//非规范性求交点
if(d1==0&&betweenCmp(c,a,b)<=0||
d2==0&&betweenCmp(d,a,b)<=0||
d3==0&&betweenCmp(a,c,d)<=0||
d1==0&&betweenCmp(b,c,d)<=0)
{
if(d1==0) p.x=c.x,p.y=c.y;
if(d2==0) p.x=d.x,p.y=d.y;
if(d3==0) p.x=a.x,p.y=a.y;
if(d4==0) p.x=b.x,p.y=b.y;
return 2;
}
return 0;
}
int main()
{
point p[4],p1;
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)!=EOF)
{
segcross(p[0],p[1],p[2],p[3],p1);
printf("%.2lf %.2lf\n",p1.x,p1.y);
}
return 0;
}