A Round Peg in a Ground Hole(圆与凸包)

http://poj.org/problem?id=1584

题意:判断所给的点能不能形成凸包,并判断所给的圆是否在凸包内。

改了好几天的一个题,今天才发现是输入顺序弄错了,办过的最脑残的事情。。sad

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <string.h>
  5 #include <math.h>
  6 using namespace std;
  7 const int N=1002;
  8 const double eps=1e-8;
  9 double pi=acos(-1.0);
 10 int n;
 11 struct point
 12 {
 13     double x,y;
 14     point(double x = 0,double y = 0):x(x),y(y) {}
 15     double norm()//向量的模
 16     {
 17         return sqrt(x*x+y*y);
 18     }
 19 
 20 };
 21 point operator-(const point &a,const point &b)
 22 {
 23     return point(a.x-b.x,a.y-b.y);
 24 }
 25 int cmp(double x)//精度处理
 26 {
 27     if (fabs(x) < eps)
 28         return 0;
 29     if (x > 0)
 30         return 1;
 31     return -1;
 32 
 33 }
 34 double det(const point &a,const point &b)//叉乘
 35 {
 36     return a.x*b.y-a.y*b.x;
 37 }
 38 
 39 double dot(const point &a,const point &b)//点乘
 40 {
 41     return a.x*b.x+a.y*b.y;
 42 }
 43 
 44 double dist(const point &a,const point &b)//两点间的距离
 45 {
 46     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 47 }
 48 bool PointOnSegment(point p,point s,point t)//判断点是否在线段上
 49 {
 50     return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0;
 51 }
 52 
 53 double dis_point_segment(const point p,const point s,const point t)//点到线段的距离
 54 {
 55     if(cmp(dot(p-s,t-s))<0) return (p-s).norm();
 56     if(cmp(dot(p-t,s-t))<0) return (p-t).norm();
 57     return fabs(det(s-p,t-p)/dist(s,t));
 58 }
 59 bool is_convex(point *p)//判断凸包
 60 {
 61     int pre = 0;
 62     p[n] = p[0];
 63     p[n+1] = p[1];
 64     for (int i = 2; i <= n; i++)
 65     {
 66         int dir = cmp(det(p[i-1]-p[i-2],p[i]-p[i-1]));
 67         if (!pre)
 68             pre = dir;
 69         if (pre*dir < 0) return false;
 70     }
 71     return true;
 72 }
 73 int point_in(point t,point *ch)//判断点是否在凸包内
 74 {
 75     int num=0,d1,d2,k;
 76     ch[n]=ch[0];
 77     for(int i=0; i<n; i++)
 78     {
 79         if(PointOnSegment(t,ch[i],ch[i+1])) return 2;
 80         k=cmp(det(ch[i+1]-ch[i],t-ch[i]));
 81         d1=cmp(ch[i].y-t.y);
 82         d2=cmp(ch[i+1].y-t.y);
 83         if(k>0&&d1<=0&&d2>0) num++;
 84         if(k<0&&d2<=0&&d1>0) num--;
 85     }
 86     return num!=0;
 87 }
 88 int main()
 89 {
 90     double x,y,r;
 91     while(~scanf("%d",&n))
 92     {
 93         if (n < 3)
 94             break;
 95         point p[N];
 96         scanf("%lf%lf%lf",&r,&x,&y);
 97         point t(x,y);
 98         for (int i = 0; i < n; i++)
 99         {
100             scanf("%lf%lf",&p[i].x,&p[i].y);
101         }
102         p[n] = p[0];//连接首尾的点
103         if (!is_convex(p))
104         {
105             printf("HOLE IS ILL-FORMED\n");
106             continue;
107         }
108         if(point_in(t,p))
109         {
110             double Min = dis_point_segment(t,p[0],p[1]);
111             for (int i = 1; i < n; i++)
112             {
113                 double dis = dis_point_segment(t,p[i],p[i+1]);
114                 Min = min(dis,Min);//圆心到所有线段的最小距离
115             }
116             if (cmp(Min-r)>= 0)
117                 printf("PEG WILL FIT\n");
118             else
119                 printf("PEG WILL NOT FIT\n");
120         }
121         else
122             printf("PEG WILL NOT FIT\n");
123 
124     }
125     return 0;
126 }
View Code

 

 

posted @ 2013-11-09 13:32  N_ll  阅读(250)  评论(0编辑  收藏  举报