POJ 1584 A Round Peg in a Ground Hole 圆是否包含在凸包内
首先判断是否是逆时针给出的多边形。
用叉积判断即可。
如果不是逆时针,就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 50000001using 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;}