2009年12月6日星期日.sgu124

2009年12月6日星期日.sgu124

2009年12月6日星期日.sgu124

sgu124:判断点在多边形内还是外还是边上
由于线段是随机给出的,没有顺时针或者逆时针顺序,所以转角法是不能用的
主要考虑射线法

射线法可以参考黑数P379,有详细的讲解,也很好理解
trick
1.要注意平行线段的处理,其实出现射线穿过线段端点的情况,完全和可以忽略
2.判断线段和射线相交时,要注意判断交点是不是在射线上也就是
对于射线L:P0 + s*v ,(s >= 0) 要注意判断交点在s >= 0时才算相交

其他就没有了。
做sgu的题真锻炼,已经很久没期待过1Y了...
 1 
 2  /*
 3   * SOUR:sgu124
 4   * ALGO:computational geometry
 5   * DATE: 2009年 12月 06日 星期日 20:50:13 CST
 6   * COMM:3
 7   *  */
 8  #include < iostream >
 9  #include < cstdio >
10  #include < cstdlib >
11  #include < cstring >
12  #include < algorithm >
13  using   namespace  std;
14  typedef  long   long  LL;
15  const   int  maxint  =   0x7fffffff ;
16  const   long   long  max64  =  0x7fffffffffffffffll;
17 
18  const   int  N  =   10100 ;
19  const   double  eps  =  1e - 10 ;
20  int  dcmp( double  x) {  return  (x  >  eps)  -  (x  <   - eps);}
21  struct  point_t {
22       double  x, y;
23      point_t (){}
24      point_t ( double  a, double  b){x  =  a,y  =  b;}
25  }p[N][ 2 ],core;
26  point_t  operator   +  (point_t a,point_t b) {  return  point_t(a.x  +  b.x,a.y  +  b.y);}
27  point_t  operator   -  (point_t a,point_t b) {  return  point_t(a.x  -  b.x,a.y  -  b.y);}
28  double  dot_mul(point_t a,point_t b) {  return  a.x  *  b.x  +  a.y  *  b.y;}
29  double  cross_mul(point_t a,point_t b) {  return  a.x  *  b.y  -  a.y  *  b.x;}
30  double  cross_mul(point_t a,point_t b,point_t c) {  return  cross_mul(a - c,b - c);}
31  double  dist2(point_t a,point_t b) {  return  (a.x - b.x) * (a.x - b.x)  +  (a.y - b.y) * (a.y - b.y);}
32 
33  bool  judge(point_t a,point_t b,point_t c,point_t d)
34  {
35       if (dcmp(cross_mul(a - c,d - c))  *  dcmp(cross_mul(b - c,d - c))  <   0 ) {
36           if (dcmp(cross_mul(a - b,c - b))  >   0 // 射线端
37               return   true ;
38      }
39       return   false ;
40  }
41 
42  int  n;
43  bool  rel(point_t a,point_t b,point_t c)
44       // a 和线段bc
45  {
46       double  tmp  = (dot_mul(a - b,c - b)  /  dist2(b,c)) ;
47       // printf("rel = %f\n",tmp);
48       return  tmp  >=   0   &&  tmp  <=   1 ;
49  }
50 
51  void  work()
52  {
53       int  sum  =   0 ;
54      point_t to  =  core;
55      to.x  +=   1 ; // 随便取的射线
56      to.y  +=   7 ;
57       for ( int  i  =   0 ;i  <  n ;i ++ ) {
58           if ( 0   ==  dcmp(cross_mul(p[i][ 1 -  p[i][ 0 ],core - p[i][ 0 ]))  &&
59                  rel(core,p[i][ 0 ],p[i][ 1 ])) {
60              printf( " BORDER\n " );
61               return ;
62          }
63           if (judge(p[i][ 0 ],p[i][ 1 ],core,to))
64              sum ++ ;
65      }
66       // printf("sum=%d\n",sum);
67       if (sum  &   1 ) {
68          printf( " INSIDE\n " );
69      } else  {
70          printf( " OUTSIDE\n " );
71      }
72  }
73 
74  int  main()
75  {
76       int  i,j,k;
77      scanf( " %d " , & n);
78       for (i  =   0 ;i  <  n;i ++ ) {
79          scanf( " %lf%lf%lf%lf " , & p[i][ 0 ].x, & p[i][ 0 ].y, & p[i][ 1 ].x, & p[i][ 1 ].y);
80 
81           if (p[i][ 0 ].y  <  p[i][ 1 ].y) {  // 保证线段总是指向左上的
82              swap(p[i][ 0 ],p[i][ 1 ]);
83          } else   if (p[i][ 0 ].y  ==  p[i][ 1 ].y  &&  p[i][ 0 ].x  >  p[i][ 1 ].x) {
84              swap(p[i][ 0 ],p[i][ 1 ]);
85          }
86      }
87      scanf( " %lf%lf " , & core.x, & core.y);
88      work();
89       return   0 ;
90  }
91 
92 


你可能感兴趣的:(2009年12月6日星期日.sgu124)