这道题我刚开始是直接求出直线交点,然后再判断是否在线段上,不知道为什么wa了。
后来看了discuss,看到有个挺好的方法:
当点A和点B在线段2的两侧,并且点C和点D在线段1的两侧时,两线段相交,否则不相交
之后一次过的,纪念下
#include<stdio.h>
#include<math.h>
#define eps 1e-9
struct segment
{
double a,c,b;
double x1,x2,y1,y2;
}f[105];
void calcu(double x1,double y1,double x2,double y2,int s)//求出直线ax+by+c=0
{
segment p;
if(fabs(x1-x2)<eps)
{
p.a=0;p.b=1;p.c=-x1;
}
else if(fabs(y1-y2)<eps)
{
p.a=1;p.b=0;p.c=-y1;
}
else
{
p.a=1;p.b=(x2-x1)/(y1-y2);p.c=-x1-p.b*y1;
}
p.x1=x1;p.x2=x2;
p.y1=y1;p.y2=y2;
f[s]=p;
}
double online(segment l,double x,double y)
{
return l.a*x+l.b*y+l.c;
}
bool judge(segment l1,segment l2)
{
if(online(l1,l2.x1,l2.y1)*online(l1,l2.x2,l2.y2)>0)//判断是否在同一侧,注意,有一个端点在线段上也算是在不同侧
return 0;
if(online(l2,l1.x1,l1.y1)*online(l2,l1.x2,l1.y2)>0)
return 0;
return 1;
}
int main()
{
int i,j,k,n;
double x1,x2,y1,y2;
while(scanf("%d",&n)!=-1&&n)
{
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
calcu(x1,y1,x2,y2,i);
}
int ans=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(judge(f[i],f[j]))
ans++;
printf("%d\n",ans);
}
return 0;
}