A Round Peg in a Ground Hole--POJ 1584

1、题目类型:模拟、计算几何。

2、解题思路:(1)检测是否为凹多边形;(2)检测圆心是否在凸多边形内部;(3)检测圆心到多边形所有边的距离是否小于半径 (具体见实现代码)。

3、注意事项:注意多边形的顺时针和逆时针,由于上的是模板,所以细节考虑并不多。

4、实现方法:

#include<iostream>
#include
<cmath>
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
using namespace std;

struct Point
{
double x,y;
};

int n;
double r;
Point P[
160];
Point c;

//检测是否为凹多边形: *p表示为多边形序列,n表示为多边形顶点数
int Check1(Point *p,int n)
{
int i,j,k,flag = 0;
double z;
if (n < 3)
return (0);
for (i=0;i<n;i++)
{
j
= (i + 1) % n;
k
= (i + 2) % n;
z
= (p[j].x - p[i].x) * (p[k].y - p[j].y);
z
-= (p[j].y - p[i].y) * (p[k].x - p[j].x);
if (z < 0)
flag
|= 1;
else if (z > 0)
flag
|= 2;
if (flag == 3)
return 0;
}
if (flag != 0)
return 1;
else
return 0;
}

// 检测点是否在多边形内: *polygon表示为多边形序列,n表示为多边形顶点数,p表示为点
int Check2(Point *polygon,int N,Point p)
{
int i,counter = 0;
double xinters;
Point p1,p2;
p1
= polygon[0];
for (i=1;i<=N;i++)
{
p2
= polygon[i % N];
if (p.y > MIN(p1.y,p2.y))
{
if (p.y <= MAX(p1.y,p2.y))
{
if (p.x <= MAX(p1.x,p2.x))
{
if (p1.y != p2.y)
{
xinters
= (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
if (p1.x == p2.x || p.x <= xinters)
counter
++;
}
}
}
}
p1
= p2;
}
if (counter % 2 == 0)
return 1;
else
return 0;
}

//计算点到线段的最短距离:p1,p2表示线段的两点,q表示距离点
double Mindistance(Point p1,Point p2,Point q)
{
int flag=1;
double k;
Point s;
if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}
if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}
if (flag)
{
k
=(p2.y-p1.y)/(p2.x-p1.x);
s.x
=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);
s.y
=k*(s.x-p1.x)+p1.y;
}
if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))
return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));
else
return MIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),
sqrt((q.x
-p2.x)*(q.x-p2.x)+(q.y-p2.y)*(q.y-p2.y)));
}

int Check3()
{
int i;
P[n].x
=P[0].x;
P[n].y
=P[0].y;
for(i=0;i<n;i++)
{
if(Mindistance(P[i],P[i+1],c)<r)
return 0;
}
return 1;
}

void Solve()
{
if(!Check1(P,n))
{
cout
<<"HOLE IS ILL-FORMED"<<endl;
return ;
}
if(Check2(P,n,c))
{
cout
<<"PEG WILL NOT FIT"<<endl;
return ;
}
if(!Check3())
{
cout
<<"PEG WILL NOT FIT"<<endl;
return ;
}
else
{
cout
<<"PEG WILL FIT"<<endl;
return ;
}
}

int main()
{
int i;
while(cin>>n && n>=3)
{
cin
>>r>>c.x>>c.y;
for(i=0;i<n;i++)
{
cin
>>P[i].x>>P[i].y;
}
Solve();
}
return 0;
}

 

posted @ 2010-10-06 17:14  勇泽  阅读(338)  评论(0编辑  收藏  举报