题意:先判断多边形是不是凸包,再判断圆是否在多边形内。
题解:凸包判断+圆与多边形位置关系
注意几点:
①半径可能为0
②内切也算在多边形内
③共线边
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 160;
//Compares a double to zero
int sgn(double x) {
if (fabs(x) < eps) return 0;
if (x < 0) return -1;
else return 1;
}
//POINT
struct Point {
double x, y;
Point() {}
Point(double _x, double _y) {
x = _x;
y = _y;
}
//返回两点的距离
double distance(Point p) {
return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
}
bool operator == (Point b)const {
return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
}
Point operator -(const Point& b)const {
return Point(x - b.x, y - b.y);
}
//叉积
double operator ^(const Point& b)const {
return x * b.y - y * b.x;
}
//点积
double operator *(const Point& b)const {
return x * b.x + y * b.y;
}
};
//LINE
struct Line {
Point s, e;
Line() {}
Line(Point _s, Point _e) {
s = _s;
e = _e;
}
//求线段长度
double length() {
return s.distance(e);
}
// 点在线段上的判断
bool pointonseg(Point p) {
return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s) * (p - e)) <= 0;
}
//点到直线的距离
double dispointtoline(Point p) {
return fabs((p - s) ^ (e - s)) / length();
}
//点到线段的距离
double dispointtoseg(Point p) {
if (sgn((p - s) * (e - s)) < 0 || sgn((p - e) * (s - e)) < 0)
return min(p.distance(s), p.distance(e));
return dispointtoline(p);
}
};
//圆
struct circle {
Point p;//圆心
double r;//半径
circle() {}
circle(double x, double y, double _r) {
p = Point(x, y);
r = _r;
}
//线段和圆的关系
//比较的是圆心到线段的距离和半径的关系
int relationseg(Line v) {
double dst = v.dispointtoseg(p);
if (sgn(dst - r) < 0)return 2;
else if (sgn(dst - r) == 0)return 1;
return 0;
}
};
//多边形
struct polygon {
int n;
Point p[maxp];
Line l[maxp];
void getline() {
for (int i = 0; i < n; i++) {
l[i] = Line(p[i], p[(i + 1) % n]);
}
}
//判断是不是凸的
bool isconvex() {
bool s[3];
memset(s, false, sizeof(s));
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
int k = (j + 1) % n;
s[sgn((p[j]-p[i]) ^ (p[k]-p[i])) + 1] = true;
if (s[0] && s[2])return false;
}
return true;
}
//判断点和任意多边形的关系
// 3 点上
// 2 边上
// 1 内部
// 0 外部
int relationpoint(Point q) {
for (int i = 0; i < n; i++) {
if (p[i] == q)return 3;
}
getline();
for (int i = 0; i < n; i++) {
if (l[i].pointonseg(q))return 2;
}
int cnt = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
int k = sgn((q-p[j]) ^ (p[i]-p[j]));
int u = sgn(p[i].y-q.y);
int v = sgn(p[j].y-q.y);
if (k > 0 && u < 0 && v >= 0)cnt++;
if (k < 0 && v < 0 && u >= 0)cnt--;
}
return cnt != 0;
}
//多边形和圆关系
// 2 圆完全在多边形内
// 1 圆在多边形里面,碰到了多边形边界
// 0 其它
int relationcircle(circle c) {
getline();
int x = 2;
if (relationpoint(c.p) != 1)return 0;//圆心不在内部
for (int i = 0; i < n; i++) {
if (c.relationseg(l[i]) == 2)return 0;
if (c.relationseg(l[i]) == 1)x = 1;
}
return x;
}
};
int n;
double r, x, y;
int main() {
while (~scanf("%d", &n) && n >= 3) {
scanf("%lf%lf%lf", &r, &x, &y);
circle cir = circle(x, y, r);
polygon pol;
pol.n = n;
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &x, &y);
pol.p[i] = Point(x, y);
}
if (!pol.isconvex()) {
puts("HOLE IS ILL-FORMED");
}
else if (r == 0) {
if(pol.relationpoint(cir.p)) puts("PEG WILL FIT");
else puts("PEG WILL NOT FIT");
}
else {
int re = pol.relationcircle(cir);
if (re) puts("PEG WILL FIT");
else puts("PEG WILL NOT FIT");
}
}
return 0;
}