首先判断是否是逆时针给出的多边形。
用叉积判断即可。
如果不是逆时针,就reverse成逆时针的。
然后判断是否是凸包,还是用叉积。
然后就判断圆心是否在凸包内
很好判断,用叉积,逆时针扫一遍点就行。
然后就要判断圆心到各个边得距离要大于半径。
这里最好用叉积,以免丢了精度,
叉积就是那个四边形的面积,除以边长就是点到边得垂直距离。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 100005
#define MAXM 211111
#define eps 1e-8
#define INF 50000001
using namespace std;
inline int dblcmp(double d)
{
if(fabs(d) < eps) return 0;
return d > eps ? 1 : -1;
}
struct point
{
double x, y;
point(){}
point(double _x, double _y): x(_x), y(_y) {}
void input()
{
scanf("%lf%lf", &x, &y);
}
bool operator ==(point a)const
{
return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;
}
point sub(point p)
{
return point(x - p.x, y - p.y);
}
double dot(point p)
{
return x * p.x + y * p.y;
}
double det(point p)
{
return x * p.y - y * p.x;
}
double distance(point p)
{
return hypot(x - p.x, y - p.y);
}
}p[33333], cir;
double r;
int n;
bool isconvex()
{
for(int i = 0; i < n; i++)
if(dblcmp(p[(i + 1) % n].sub(p[i]).det(p[(i + 2) % n].sub(p[i]))) < 0) return false;
return true;
}
bool inconvex()
{
for(int i = 0; i < n; i++)
if(dblcmp(p[i].sub(cir).det(p[(i + 1) % n].sub(cir))) < 0) return false;
return true;
}
bool checkdist()
{
for(int i = 0; i < n; i++)
{
double area = p[i].sub(cir).det(p[(i + 1) % n].sub(cir));
double dis = area / (p[i].distance(p[(i + 1) % n]));
if(dblcmp(dis - r) < 0) return false;
}
return true;
}
int main()
{
while(scanf("%d", &n) != EOF)
{
if(n < 3) break;
scanf("%lf", &r); cir.input();
for(int i = 0; i < n; i++) p[i].input();
int flag = 0;
int now = 0;
while(now < n && flag == 0)
{
flag = dblcmp(p[(now + 1) % n].sub(p[now]).det(p[(now + 2) % n].sub(p[now])));
now++;
}
if(flag < 0) reverse(p, p + n);
if(!isconvex()) puts("HOLE IS ILL-FORMED");
else if(!inconvex() || !checkdist()) puts("PEG WILL NOT FIT");
else puts("PEG WILL FIT");
}
return 0;
}