poj1584

题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部。

分析:计算几何

分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;
}
原文地址:https://www.cnblogs.com/rainydays/p/2098102.html