题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部。
分析:计算几何
分3步:
1、判断是否是凸多边形
2、判断点是否在多边形内部
3、判断点到各边的距离是否大于等于半径
首先,若点是顺时针则reverse()改为逆时针,reverse函数就是用来把数组反向的。然后利用每3个相邻点组成的两条向量的叉积来判断,都应大于等于零。然后,判断是否在内部,利用钉子点和多边形每两个相邻点,组成两个向量。判断叉积是否全都大于0(全为逆时针)。再就是判断点到直线的距离,利用三角形面积除以底边,面积用叉积求。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
usingnamespace std;
#define maxn 2000
#define eps 10E-9
struct Point
{
double x, y;
Point operator-(const Point &a) const
{
Point ret;
ret.x = x - a.x;
ret.y = y - a.y;
return ret;
}
} point[maxn], peg;
double pegr;
int n;
int dblcmp(double a)
{
if (fabs(a) < eps)
return0;
return a >0?1 : -1;
}
double xmult(const Point &a, const Point &b)
{
return a.x * b.y - b.x * a.y;
}
void input()
{
scanf("%lf%lf%lf", &pegr, &peg.x, &peg.y);
for (int i =0; i < n; i++)
scanf("%lf%lf", &point[i].x, &point[i].y);
int t =0;
int i =0;
while (i < n && t ==0)
{
t = dblcmp(xmult(point[(i +1)%n] - point[i], point[(i +2)%n] - point[i]));
i++;
}
if (t <0)
reverse(point, point + n);
}
bool convex()
{
for (int i =0; i < n; i++)
if (dblcmp(xmult(point[(i +1)%n] - point[i], point[(i +2)%n] - point[(i +1)%n])) <0)
returnfalse;
returntrue;
}
bool inconvex()
{
for (int i =0; i < n; i++)
if (dblcmp(xmult(point[(i +1)%n] - point[i], peg - point[(i +1)%n])) <=0)
returnfalse;
returntrue;
}
double dist(const Point &a, const Point &b)
{
Point p;
p = a - b;
return sqrt(p.x * p.x + p.y * p.y);
}
bool ok()
{
for (int i =0; i < n; i++)
if (dblcmp(abs(xmult(peg - point[i], point[(i +1)%n] - point[i]))/dist(point[i], point[(i +1)%n]) - pegr) <0)
returnfalse;
returntrue;
}
int main()
{
//freopen("t.txt", "r", stdin);
while (scanf("%d", &n) != EOF)
{
if (n <3)
break;
input();
if (!convex())
printf("HOLE IS ILL-FORMED\n");
elseif (!inconvex()||!ok())
printf("PEG WILL NOT FIT\n");
else
printf("PEG WILL FIT\n");
}
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
usingnamespace std;
#define maxn 2000
#define eps 10E-9
struct Point
{
double x, y;
Point operator-(const Point &a) const
{
Point ret;
ret.x = x - a.x;
ret.y = y - a.y;
return ret;
}
} point[maxn], peg;
double pegr;
int n;
int dblcmp(double a)
{
if (fabs(a) < eps)
return0;
return a >0?1 : -1;
}
double xmult(const Point &a, const Point &b)
{
return a.x * b.y - b.x * a.y;
}
void input()
{
scanf("%lf%lf%lf", &pegr, &peg.x, &peg.y);
for (int i =0; i < n; i++)
scanf("%lf%lf", &point[i].x, &point[i].y);
int t =0;
int i =0;
while (i < n && t ==0)
{
t = dblcmp(xmult(point[(i +1)%n] - point[i], point[(i +2)%n] - point[i]));
i++;
}
if (t <0)
reverse(point, point + n);
}
bool convex()
{
for (int i =0; i < n; i++)
if (dblcmp(xmult(point[(i +1)%n] - point[i], point[(i +2)%n] - point[(i +1)%n])) <0)
returnfalse;
returntrue;
}
bool inconvex()
{
for (int i =0; i < n; i++)
if (dblcmp(xmult(point[(i +1)%n] - point[i], peg - point[(i +1)%n])) <=0)
returnfalse;
returntrue;
}
double dist(const Point &a, const Point &b)
{
Point p;
p = a - b;
return sqrt(p.x * p.x + p.y * p.y);
}
bool ok()
{
for (int i =0; i < n; i++)
if (dblcmp(abs(xmult(peg - point[i], point[(i +1)%n] - point[i]))/dist(point[i], point[(i +1)%n]) - pegr) <0)
returnfalse;
returntrue;
}
int main()
{
//freopen("t.txt", "r", stdin);
while (scanf("%d", &n) != EOF)
{
if (n <3)
break;
input();
if (!convex())
printf("HOLE IS ILL-FORMED\n");
elseif (!inconvex()||!ok())
printf("PEG WILL NOT FIT\n");
else
printf("PEG WILL FIT\n");
}
return0;
}