POJ 1584(计算几何初步——凸包判断,圆与多边形,点是否在多边形内)
此题让我WA了N次。。。坑呐。。。
需要注意几点(血淋淋的教训):
1.有可能出现一种情况,它给出的是5个点,但这个有可能是三角形,因为有4个点在同一边上.
2.R == 0的情况(如果点在边上时返回正确)。。
3.给出的点的顺序可能为顺时针或者逆时针。
View Code
1 #include<iostream>
2 #include<cmath>
3 #define EPS 1e-8
4 using namespace std;
5 struct point {
6 double x, y;
7 }pol[2000];
8
9 int nver;
10 point hole;
11 double R;
12
13 double ABS(double a)
14 {
15 return a>EPS?a:-a;
16 }
17
18 double max(double a, double b)
19 {
20 return a>b?a:b;
21 }
22
23 double min(double a, double b)
24 {
25 return a<b?a:b;
26 }
27
28 double cross(point &p1, point &p2, point &p3)
29 {
30 return (p3.y - p2.y)*(p2.x - p1.x) - (p3.x - p2.x)*(p2.y - p1.y);
31 }
32
33 double mul(point &p1, point &p0, point &p2)
34 {
35 return (p2.y - p0.y)*(p1.x - p0.x) - (p2.x - p0.x)*(p1.y - p0.y);
36 }
37
38 bool convex_hull(int n)
39 {
40 int flag = 0;
41 for (int i(0); i<n; ++i) {
42 if (cross(pol[i],pol[(i+1)%n],pol[(i+2)%n]) > EPS) {
43 if (flag == 1)return false;
44 else flag = 2;
45 } else {
46 if (cross(pol[i],pol[(i+1)%n],pol[(i+2)%n]) < -EPS) {
47 if (flag == 2)return false;
48 else flag = 1;
49 }
50 }
51 }
52 return true;
53 }
54
55 bool on_line(point &p1, point &p2, point &q)
56 {
57 if (min(p1.x,p2.x) + EPS <= q.x && q.x <= max(p1.x,p2.x) + EPS &&
58 min(p1.y,p2.y) + EPS <= q.y && q.y <= max(p1.y,p2.y) + EPS &&
59 cross(p1,p2,q) <= EPS && cross(p1,p2,q) >= -EPS)
60 return true;
61 return false;
62 }
63
64 int intersect(point &p1, point &p2, point &q1, point &q2)
65 {
66 if (max(p1.x,p2.x) >= min(q1.x,q2.x) && max(q1.x,q2.x) >= min(p1.x,p2.x) &&
67 max(p1.y,p2.y) >= min(q1.y,q2.y) && max(q1.y,q2.y) >= min(p1.y,p2.y)) {
68 if (mul(p1,q1,q2)*mul(q2,q1,p2) > EPS && mul(q1,p1,p2)*mul(p2,p1,q2) > EPS) return 1;
69 else if (mul(p1,q1,q2)*mul(q2,q1,p2) < -EPS || mul(q1,p1,p2)*mul(p2,p1,q2) < -EPS)return 0;
70 return -1;
71 }
72 return 0;
73 }
74
75 bool point_in(int n)
76 {
77 int flag;
78 point another;
79 another.x = 10000000;
80 another.y = hole.y;
81 int count = 0;
82 for (int i(0); i<n; ++i) {
83 if (pol[i].y == pol[(i+1)%n].y)continue;
84 if (on_line(pol[i],pol[(i+1)%n],hole)) {
85 if (R == 0)return true;
86 return false;
87 } else {
88 if ((flag = intersect(pol[i],pol[(i+1)%n],hole,another)) == 1) {
89 count++;
90 } else {
91 if (flag == -1){
92 if (max(pol[i].y,pol[(i+1)%n].y) == hole.y) {
93 count++;
94 }
95 }
96 }
97 }
98 }
99 if (count%2 == 1)return true;
100 return false;
101 }
102
103 double dist(point &q, point &p)
104 {
105 return sqrt((q.x - p.x)*(q.x - p.x) + (q.y - p.y)*(q.y - p.y));
106 }
107
108 bool fit_in(int n)
109 {
110 if (R == 0)return true;
111 for (int i(0); i<n; ++i) {
112 if (ABS(mul(pol[i],hole,pol[(i+1)%n])/dist(pol[i],pol[(i+1)%n])) + EPS < R) {
113 return false;
114 }
115 }
116 return true;
117 }
118
119 int main()
120 {
121 while (scanf("%d",&nver) && nver >= 3) {
122 scanf("%lf%lf%lf",&R,&hole.x,&hole.y);
123 for (int i(0); i<nver; ++i) {
124 scanf("%lf%lf",&pol[i].x,&pol[i].y);
125 }
126 if (convex_hull(nver)) {
127 if (point_in(nver)) {
128 if (fit_in(nver)) {
129 cout<<"PEG WILL FIT"<<endl;
130 continue;
131 }
132 }
133 } else {
134 cout<<"HOLE IS ILL-FORMED"<<endl;
135 continue;
136 }
137 cout<<"PEG WILL NOT FIT"<<endl;
138 }
139 return 0;
140 }