您的位置:首页 > 其它

POJ 1584 A Round Peg in a Ground Hole

2016-01-24 21:00 239 查看
先判断是不是N多边形,求一下凸包,如果所有点都用上了,那么就是凸多边形

判断圆是否在多边形内,

先排除圆心在多边形外的情况

剩下的情况可以利用圆心到每条边的最短距离与半径的大小来判断

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#include<algorithm>
using namespace std;

const double eps=1e-8;
const double pi=2*asin(1.0);
struct point
{
double x,y;
double alpha;
double len2;
int id;
} p[200];
int T,n;
vector<point>v;
vector<int>ans;

double MinY;
int MinId;

bool cmp(const point &a, const point &b)
{
if(fabs(a.alpha-b.alpha)<eps) return a.len2<b.len2;
return a.alpha<b.alpha;
}

double len2(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

double f(point a,point b,point c) //返回点a所对应的角的弧度
{
double B2=(double)len2(a,c);
double C2=(double)len2(a,b);
double A2=(double)len2(b,c);
double COSA=(B2+C2-A2)/(2*sqrt(B2)*sqrt(C2));
return pi-acos(COSA);
}

double GetPointDistance(point p1, point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

double GetNearestDistance(point PA, point PB, point P3)
{
double a,b,c;
a=GetPointDistance(PB,P3);
if(a<=0.00001) return 0.0f;
b=GetPointDistance(PA,P3);
if(b<=0.00001) return 0.0f;
c=GetPointDistance(PA,PB);
if(c<=0.00001) return a;
if(a*a>=b*b+c*c) return b;
if(b*b>=a*a+c*c) return a;
double l=(a+b+c)/2;
double s=sqrt(l*(l-a)*(l-b)*(l-c));
return 2*s/c;
}

bool check(point T)
{
double sum=0;
for(int i=0;i<ans.size();i++)
sum=sum+pi-(f(T,p[ans[i]],p[ans[(i+1)%ans.size()]]));
if(fabs(sum-2*pi)<eps) return 0;
return 1;
}

int main()
{
double pegRadius ,pegX ,pegY ;
while(~scanf("%d", &n))
{
if(n<3) break;
scanf("%lf%lf%lf",&pegRadius,&pegX,&pegY);
MinY=9999999999999;
for(int i=1; i<=n; i++)
{
scanf("%lf%lf", &p[i].x, &p[i].y);
p[i].id=i;
if(p[i].y<MinY)
{
MinY=p[i].y;
MinId=i;
}
}

ans.clear();

point pre; pre.x=-9999999999999; pre.y=p[MinId].y;
point now; now.x=p[MinId].x; now.y=p[MinId].y; now.id=MinId;

for(int i=1; i<=n; i++)
{
v.clear();
for(int k=1; k<=n; k++)
{
if(p[k].id!=now.id)
{
p[k].alpha=f(now,p[k],pre);
p[k].len2=len2(p[k],now);
v.push_back(p[k]);
}
}
sort(v.begin(),v.end(),cmp);
ans.push_back(v[0].id);
if(v[0].id==MinId) break;

pre.x=now.x;
pre.y=now.y;
pre.id=now.id;
now.x=v[0].x;
now.y=v[0].y;
now.id=v[0].id;
}

if(ans.size()<n) printf("HOLE IS ILL-FORMED\n");

else
{
bool fail=0;
point T;
T.x=pegX;
T.y=pegY;

if(check(T)) {fail=1;}
else
{
for(int i=0; i<ans.size(); i++)
{
double len=GetNearestDistance(p[ans[i]],p[ans[(i+1)%ans.size()]],T);
if(len+eps<=pegRadius) fail=1;
}
}

if(fail==0) printf("PEG WILL FIT\n");
else printf("PEG WILL NOT FIT\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: