POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)
A Round Peg in a Ground Hole
Description The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to one another using a wooden peg that fits into pre-cut holes in each piece to be attached. The pegs have a circular cross-section and so are intended to fit inside a round hole.
A recent factory run of computer desks were flawed when an automatic grinding machine was mis-programmed. The result is an irregularly shaped hole in one piece that, instead of the expected circular shape, is actually an irregular polygon. You need to figure out whether the desks need to be scrapped or if they can be salvaged by filling a part of the hole with a mixture of wood shavings and glue. There are two concerns. First, if the hole contains any protrusions (i.e., if there exist any two interior points in the hole that, if connected by a line segment, that segment would cross one or more edges of the hole), then the filled-in-hole would not be structurally sound enough to support the peg under normal stress as the furniture is used. Second, assuming the hole is appropriately shaped, it must be big enough to allow insertion of the peg. Since the hole in this piece of wood must match up with a corresponding hole in other pieces, the precise location where the peg must fit is known. Write a program to accept descriptions of pegs and polygonal holes and determine if the hole is ill-formed and, if not, whether the peg will fit at the desired location. Each hole is described as a polygon with vertices (x1, y1), (x2, y2), . . . , (xn, yn). The edges of the polygon are (xi, yi) to (xi+1, yi+1) for i = 1 . . . n − 1 and (xn, yn) to (x1, y1). Input Input consists of a series of piece descriptions. Each piece description consists of the following data:
Line 1 < nVertices > < pegRadius > < pegX > < pegY > number of vertices in polygon, n (integer) radius of peg (real) X and Y position of peg (real) n Lines < vertexX > < vertexY > On a line for each vertex, listed in order, the X and Y position of vertex The end of input is indicated by a number of polygon vertices less than 3. Output For each piece description, print a single line containing the string:
HOLE IS ILL-FORMED if the hole contains protrusions PEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated position PEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated position Sample Input 5 1.5 1.5 2.0 Sample Output HOLE IS ILL-FORMED Source |
首先是判断给出了多边形是不是凸多边形。
然后判断圆包含在凸多边形中。
一定要保证圆心在凸多边形里面。
然后判断圆心到每条线段的距离要大于等于半径。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h> using namespace std; const double eps = 1e-;
const double PI = acos(-1.0);
int sgn(double x)
{
if(fabs(x) < eps)return ;
if(x < )return -;
else return ;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
void input()
{
scanf("%lf%lf",&x,&y);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
}
};
//*两点间距离
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
//判断凸多边形
//允许共线边
//点可以是顺时针给出也可以是逆时针给出
//点的编号1~n-1
bool isconvex(Point poly[],int n)
{
bool s[];
memset(s,false,sizeof(s));
for(int i = ;i < n;i++)
{
s[sgn( (poly[(i+)%n]-poly[i])^(poly[(i+)%n]-poly[i]) )+] = true;
if(s[] && s[])return false;
}
return true;
}
//点到线段的距离
//返回点到线段最近的点
Point NearestPointToLineSeg(Point P,Line L)
{
Point result;
double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
if(t >= && t <= )
{
result.x = L.s.x + (L.e.x - L.s.x)*t;
result.y = L.s.y + (L.e.y - L.s.y)*t;
}
else
{
if(dist(P,L.s) < dist(P,L.e))
result = L.s;
else result = L.e;
}
return result;
}
//*判断点在线段上
bool OnSeg(Point P,Line L)
{
return
sgn((L.s-P)^(L.e-P)) == &&
sgn((P.x - L.s.x) * (P.x - L.e.x)) <= &&
sgn((P.y - L.s.y) * (P.y - L.e.y)) <= ;
}
//*判断点在凸多边形内
//点形成一个凸包,而且按逆时针排序(如果是顺时针把里面的<0改为>0)
//点的编号:0~n-1
//返回值:
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inConvexPoly(Point a,Point p[],int n)
{
for(int i = ;i < n;i++)
{
if(sgn((p[i]-a)^(p[(i+)%n]-a)) < )return -;
else if(OnSeg(a,Line(p[i],p[(i+)%n])))return ;
}
return ;
}
//*判断线段相交
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= &&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= ;
}
//*判断点在任意多边形内
//射线法,poly[]的顶点数要大于等于3,点的编号0~n-1
//返回值
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inPoly(Point p,Point poly[],int n)
{
int cnt;
Line ray,side;
cnt = ;
ray.s = p;
ray.e.y = p.y;
ray.e.x = -100000000000.0;//-INF,注意取值防止越界 for(int i = ;i < n;i++)
{
side.s = poly[i];
side.e = poly[(i+)%n]; if(OnSeg(p,side))return ; //如果平行轴则不考虑
if(sgn(side.s.y - side.e.y) == )
continue; if(OnSeg(side.s,ray))
{
if(sgn(side.s.y - side.e.y) > )cnt++;
}
else if(OnSeg(side.e,ray))
{
if(sgn(side.e.y - side.s.y) > )cnt++;
}
else if(inter(ray,side))
cnt++;
}
if(cnt % == )return ;
else return -;
}
Point p[];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
double R,x,y;
while(scanf("%d",&n) == )
{
if(n < )break;
scanf("%lf%lf%lf",&R,&x,&y);
for(int i = ;i < n;i++)
p[i].input();
if(!isconvex(p,n))
{
printf("HOLE IS ILL-FORMED\n");
continue;
}
Point P = Point(x,y);
if(inPoly(P,p,n) < )
{
printf("PEG WILL NOT FIT\n");
continue;
}
bool flag = true;
for(int i = ;i < n;i++)
{
if(sgn(dist(P,NearestPointToLineSeg(P,Line(p[i],p[(i+)%n]))) - R) < )
{
flag = false;
break;
}
}
if(flag)printf("PEG WILL FIT\n");
else printf("PEG WILL NOT FIT\n");
}
return ;
}
POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)的更多相关文章
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内
首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...
- 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 1584 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 ...
- 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 --判定点在形内形外形上
题意: 给一个圆和一个多边形,多边形点可能按顺时针给出,也可能按逆时针给出,先判断多边形是否为凸包,再判断圆是否在凸包内. 解法: 先判是否为凸包,沿着i=0~n,先得出初始方向dir,dir=1为逆 ...
- 简单几何(点的位置) POJ 1584 A Round Peg in a Ground Hole
题目传送门 题意:判断给定的多边形是否为凸的,peg(pig?)是否在多边形内,且以其为圆心的圆不超出多边形(擦着边也不行). 分析:判断凸多边形就用凸包,看看点集的个数是否为n.在多边形内用叉积方向 ...
- POJ 1584 A Round Peg in a Ground Hole
先判断是不是N多边形,求一下凸包,如果所有点都用上了,那么就是凸多边形 判断圆是否在多边形内, 先排除圆心在多边形外的情况 剩下的情况可以利用圆心到每条边的最短距离与半径的大小来判断 #include ...
- 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 ...
随机推荐
- C#处理文件流的转换
//----引入必要的命名空间 using System.IO; using System.Drawing.Imaging; //----代码部分----// private byte[] photo ...
- 一个发光的搜索边框(纯CSS3)
这是效果图,边框会不停的闪,兼容各种浏览器 HTML代码: <body> <div class="container"> <form method=& ...
- HDU 3448 Bag Problem
这是一道搜索的背包题目 题意: 有n件物品从中最多选m件,使其总重量不超过v,求能获得的最大重量 有一个很重要的剪枝(是数据的问题还是这个剪枝本身很高效?): 如果重量最大m件物品都不超过v,则答案就 ...
- 51nod1225 余数之和
打表可以看出规律.分块求就可以了. #include<cstdio> #include<cstring> #include<cctype> #include< ...
- POJ 1422 Air Raid (最小路径覆盖)
题意 给定一个有向图,在这个图上的某些点上放伞兵,可以使伞兵可以走到图上所有的点.且每个点只被一个伞兵走一次.问至少放多少伞兵. 思路 裸的最小路径覆盖. °最小路径覆盖 [路径覆盖]在一个有向图G( ...
- 使用WINRAR来制作安装程序
1. WINRAR版本 2. 将所有文件放在同一个文件夹下 3. 选中所有文件点击右键 -> Add to archive 4. General设置 5. Advanced 设置 6. 确定开始 ...
- 流程引擎的API和服务基础
RepositoryService : 管理和控制 发布包 和 流程定义(包含了一个流程每个环节的结构和行为) 的操作 除此之外,服务可以 查询引擎中的发布包和流程定义. 暂停或激活发布包,对应全部 ...
- 解决mysql中文乱码(总)
转自:http://hi.baidu.com/cnvienna/blog/item/2e99efdfd94fc61862279801.html MySQL会出现中文乱码的原因不外乎下列几点: .ser ...
- Android MVPR 架构模式
最近我在尝试让 Google 的 IO App 变得可单元测试,我这样做的其中一个原因是验证 Freeman 和 Pryce 在引用中对单元测试的总结.即使现在我还是没有把 IOSched 中的任何一 ...
- SSH框架面试题
Hibernate工作原理及为什么要用? 原理: 1. 读取并解析配置文件 2. 读取并解析映射信息,创建SessionFactory 3. 打开Sesssion 4. 创建事务Transation ...