您的位置:首页 > 其它

hdu 1086 判断两个线段是否相交

2012-03-22 16:04 399 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086

第三个问题,以下两个条件,至少满足一个,即可断定两线段相交:

1)每个线段都跨越(straddle)包含了另一线段的直线(即最普通的相交)

2)一个线段的某一个端点位于另一线段上(边界情况,包含重合)

View Code

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct ss{
double x,y;
}a[105],b[105];
double direction(ss p1,ss p2,ss p0) //叉积判断线段的相对位置(返回值大于零p1在p2的顺时针方向上。)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double min(double x,double y)
{
if(x>y)return y;
else return x;
}
double  max(double x,double y)
{
if(x>y)return x;
else return y;
}
bool OnSegment(ss p1,ss p2,ss p0) //判断点po在点p1和p2点所构成的矩阵中
{
if (min(p1.x, p2.x) <= p0.x && p0.x <= max(p1.x, p2.x) &&min(p1.y, p2.y) <= p0.y&& p0.y <= max(p1.y,p2.y))
return true;
else return false;
}

/************************************************************************/
/* 两线段相交分两种情况:1,两线段相交
2,一个线段的顶点在另一个线段上,这是边界条件                           */
/************************************************************************/
int judge(ss p1,ss p2,ss p3,ss p4)
{
double d1,d2,d3,d4;
d1=direction(p3,p4,p1);
d2=direction(p3,p4,p2);
d3=direction(p1,p2,p3);
d4=direction(p1,p2,p4);
if(d1*d2<0&&d3*d4<0)return true;//两线段相交的情况
else if(d1==0.0&&OnSegment(p3,p4,p1))return true;
else if(d2==0.0&&OnSegment(p3,p4,p2))return true;
else  if(d3==0.0&&OnSegment(p1,p2,p3))return true;
else  if(d4==0.0&&OnSegment(p1,p2,p4))return true;
return false;
}
int main()
{
int n,i,j,ans;
while (scanf("%d",&n)&&n)
{
for (i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y);
}
ans=0;
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
{
if(judge(a[i],b[i],a[j],b[j]))
ans++;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: