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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086

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

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

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

View Code
 1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 using namespace std;
5 struct ss{
6 double x,y;
7 }a[105],b[105];
8 double direction(ss p1,ss p2,ss p0) //叉积判断线段的相对位置(返回值大于零p1在p2的顺时针方向上。)
9 {
10 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
11 }
12 double min(double x,double y)
13 {
14 if(x>y)return y;
15 else return x;
16 }
17 double max(double x,double y)
18 {
19 if(x>y)return x;
20 else return y;
21 }
22 bool OnSegment(ss p1,ss p2,ss p0) //判断点po在点p1和p2点所构成的矩阵中
23 {
24 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))
25 return true;
26 else return false;
27 }
28
29 /************************************************************************/
30 /* 两线段相交分两种情况:1,两线段相交
31 2,一个线段的顶点在另一个线段上,这是边界条件 */
32 /************************************************************************/
33 int judge(ss p1,ss p2,ss p3,ss p4)
34 {
35 double d1,d2,d3,d4;
36 d1=direction(p3,p4,p1);
37 d2=direction(p3,p4,p2);
38 d3=direction(p1,p2,p3);
39 d4=direction(p1,p2,p4);
40 if(d1*d2<0&&d3*d4<0)return true;//两线段相交的情况
41 else if(d1==0.0&&OnSegment(p3,p4,p1))return true;
42 else if(d2==0.0&&OnSegment(p3,p4,p2))return true;
43 else if(d3==0.0&&OnSegment(p1,p2,p3))return true;
44 else if(d4==0.0&&OnSegment(p1,p2,p4))return true;
45 return false;
46 }
47 int main()
48 {
49 int n,i,j,ans;
50 while (scanf("%d",&n)&&n)
51 {
52 for (i=1;i<=n;i++)
53 {
54 scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y);
55 }
56 ans=0;
57 for (i=1;i<=n;i++)
58 for (j=i+1;j<=n;j++)
59 {
60 if(judge(a[i],b[i],a[j],b[j]))
61 ans++;
62 }
63 printf("%d\n",ans);
64 }
65 return 0;
66 }



posted @ 2012-03-22 16:04  我们一直在努力  阅读(219)  评论(0编辑  收藏  举报