POJ1584 A Round Peg in a Ground Hole 凸包判断 圆和凸包的关系
题意:给定n条边首尾相连对应的n个点 判断构成的图形是不是凸多边形
然后给一个圆 判断圆是否完全在凸包内(相切也算)
思路:首先运用叉积判断凸多边形 相邻三条边叉积符号相异则必有凹陷 O(n)
之后首先判断圆心是否在凸多边形内 如果凸多边形的点有序 则可以在logn时间内判断 否则先排序再判断 O(nlogn)
然后用每条边(线段)判断到圆心的距离即可
这道题也没给数据范围 O(nlogn)是可以AC的。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std; const double eps=1e-9; int cmp(double x)
{
if(fabs(x)<eps)return 0;
if(x>0)return 1;
else return -1;
} const double pi=acos(-1.0); inline double sqr(double x)
{
return x*x;
} struct point
{
double x,y;
point (){}
point (double a,double b):x(a),y(b){}
void input()
{
scanf("%lf%lf",&x,&y);
}
friend point operator +(const point &a,const point &b)
{
return point(a.x+b.x,a.y+b.y);
}
friend point operator -(const point &a,const point &b)
{
return point(a.x-b.x,a.y-b.y);
}
friend bool operator ==(const point &a,const point &b)
{
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
}
friend point operator *(const point &a,const double &b)
{
return point(a.x*b,a.y*b);
}
friend point operator*(const double &a,const point &b)
{
return point(a*b.x,a*b.y);
}
friend point operator /(const point &a,const double &b)
{
return point(a.x/b,a.y/b);
}
double norm()
{
return sqrt(sqr(x)+sqr(y));
}
}; struct line
{
point a,b;
line(){};
line(point x,point y):a(x),b(y)
{ }
};
double det(const point &a,const point &b)
{
return a.x*b.y-a.y*b.x;
} double dot(const point &a,const point &b)
{
return a.x*b.x+a.y*b.y;
} double dist(const point &a,const point &b)
{
return (a-b).norm();
} point rotate_point(const point &p,double A)
{
double tx=p.x,ty=p.y;
return point(tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
} bool parallel(line a,line b)
{
return !cmp(det(a.a-a.b,b.a-b.b));
} bool line_joined(line a,line b,point &res)
{
if(parallel(a,b))return false;
double s1=det(a.a-b.a,b.b-b.a);
double s2=det(a.b-b.a,b.b-b.a);
res=(s1*a.b-s2*a.a)/(s1-s2);
return true;
} bool pointonSegment(point p,point s,point t)
{
return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0;
} void PointProjLine(const point p,const point s,const point t,point &cp)
{
double r=dot((t-s),(p-s))/dot(t-s,t-s);
cp=s+r*(t-s);
} struct polygon_convex
{
vector<point>P;
polygon_convex(int Size=0)
{
P.resize(Size);
}
}; bool comp_less(const point &a,const point &b)
{
return cmp(a.x-b.x)<0||cmp(a.x-b.x)==0&&cmp(a.y-b.y)<0; } polygon_convex convex_hull(vector<point> a)
{
polygon_convex res(2*a.size()+5);
sort(a.begin(),a.end(),comp_less);
a.erase(unique(a.begin(),a.end()),a.end());//删去重复点
int m=0;
for(int i=0;i<a.size();i++)
{
while(m>1&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
int k=m;
for(int i=int(a.size())-2;i>=0;--i)
{
while(m>k&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
res.P.resize(m);
if(a.size()>1)res.P.resize(m-1);
return res;
} bool is_convex(vector<point> &a)
{
for(int i=0;i<a.size();i++)
{
int i1=(i+1)%int(a.size());
int i2=(i+2)%int(a.size());
int i3=(i+3)%int(a.size());
if((cmp(det(a[i1]-a[i],a[i2]-a[i1]))*cmp(det(a[i2]-a[i1],a[i3]-a[i2])))<0)
return false;
}
return true;
}
int containO(const polygon_convex &a,const point &b)
{
int n=a.P.size();
point g=(a.P[0]+a.P[n/3]+a.P[2*n/3])/3.0;
int l=0,r=n;
while(l+1<r)
{
int mid=(l+r)/2;
if(cmp(det(a.P[l]-g,a.P[mid]-g))>0)
{
if(cmp(det(a.P[l]-g,b-g))>=0&&cmp(det(a.P[mid]-g,b-g))<0)r=mid;
else l=mid;
}else
{
if(cmp(det(a.P[l]-g,b-g))<0&&cmp(det(a.P[mid]-g,b-g))>=0)l=mid;
else r=mid;
}
}
r%=n;
int z=cmp(det(a.P[r]-b,a.P[l]-b))-1;
if(z==-2)return 1;
return z;
} bool circle_in_polygon(point cp,double r,polygon_convex &pol)
{ polygon_convex pp=convex_hull(pol.P);
if(containO(pp,cp)!=1)return false;
for(int i=0;i<pol.P.size();i++)
{
int j;
if(i<pol.P.size()-1)j=i+1;
else j=0;
point prol;
PointProjLine(cp,pol.P[i],pol.P[j],prol);
double dis;
if(pointonSegment(prol,pol.P[i],pol.P[j]))dis=dist(prol,cp);
else dis=min(dist(cp,pol.P[i]),dist(pol.P[j],cp));
if(cmp(dis-r)==-1)return false;
}
return true;
}
vector<point>pn;
int main()
{freopen("t.txt","r",stdin);
//freopen("1.txt","w",stdout);
int n;
while(scanf("%d",&n)&&n>=3)
{pn.resize(n);
double ra;scanf("%lf",&ra);
point cc;cc.input();
for(int i=0;i<n;i++)
pn[i].input();
polygon_convex pc;
if(!is_convex(pn)){printf("HOLE IS ILL-FORMED\n");continue;}
pc.P=pn;
if(circle_in_polygon(cc,ra,pc)){printf("PEG WILL FIT\n");continue;}
else {printf("PEG WILL NOT FIT\n");continue;}
}
return 0;
}
POJ1584 A Round Peg in a Ground Hole 凸包判断 圆和凸包的关系的更多相关文章
- POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4438 Acc ...
- poj1584 A round peg in a ground hole【计算几何】
含[判断凸包],[判断点在多边形内],[判断圆在多边形内]模板 凸包:即凸多边形 用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点. The ...
- poj1584 A Round Peg in a Ground Hole 判断多边形凹凸,点到线的距离【基础计算几何】
大致思路:首先对于所给的洞的点,判断是否是凸多边形,图形的输入和输出可以是顺时针或者逆时针,而且允许多点共线 Debug 了好几个小时,发现如下问题 判断三点是否共线,可用斜率公式判断 POINT p ...
- POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)
http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内
首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...
- A Round Peg in a Ground Hole(凸包应用POJ 1584)
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5684 Accepte ...
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,判断点在凸多边形内
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5456 Acc ...
- POJ 1584 A Round Peg in a Ground Hole[判断凸包 点在多边形内]
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6682 Acc ...
- POJ 1518 A Round Peg in a Ground Hole【计算几何=_=你值得一虐】
链接: http://poj.org/problem?id=1584 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
随机推荐
- CSS——可视化格式模型
CSS的可视化格式模型 CSS中规定每一个元素都有自己的盒子模型(相当一规定了这个元素如何显示): 然后可视化格式模型则是把这些盒子模型按照规则摆放到页面上,也就是如何布局: 换句话说,盒子模型规定了 ...
- 字符串类String类的判断功能
StringDemo.java /* * Object:是类层级结构中的根类,所有的类都直接或间接的继承自该类. * 如果一个方法的形式参数是Object,那么这里我们就可以传递它的任意的子类对象. ...
- Thawte 企业版代码签名证书
Thawte企业版代码签名证书 ,严格验证企业身份,如果您是个人开放者,请申请Thawte 个人代码签名证书.Thawte企业代码签名证书 可帮助程序开发者使用微软代码签名工具(Microsoft ...
- Avro kafka(Producer-Consumer)
https://blog.csdn.net/mlljava1111/article/details/51376990
- Memcached的几种Java客户端(待实践)
其实现在来尝试Memcached的客户端估计会有点过气,因为现在大势基本都在Redis那边. Memcached Client目前有3种: Memcached Client for Java(已经停止 ...
- Mybatis 增强工具包 Mybatis-Plus
原文:https://www.oschina.net/p/mybatis-plus
- 【SSH进阶之路】Hibernate搭建开发环境+简单实例(二)
Hibernate是很典型的持久层框架,持久化的思想是很值得我们学习和研究的.这篇博文,我们主要以实例的形式学习Hibernate,不深究Hibernate的思想和原理,否则,一味追求,苦学思想和原理 ...
- 制作svg动画
要实现一步一步画出来一个图片,css3做不到吧.除非一张张的图片定时显示.想不到别的招了.如今用的是一个插件,做了一个svg动画. 插件地址:http://lazylinepainter.info/ ...
- leetcode第一刷_Best Time to Buy and Sell Stock
这样的题就不要去考虑N^2的算法了.肯定会超时的.乍一看,非常可能会想到贪心,可是普通的贪心思路是不行的,比方想找到一个最小值用来买入.尽管它跟最大值之间的差一定是最好的,可是最大值出如今它前面就不行 ...
- SDUST 2844-Mineral Water(数学)
Mineral Water nid=24#time" title="C.C++.go.haskell.lua.pascal Time Limit1000ms Memory Limi ...