POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,点到线段距离,点在多边形内
ACM博客_kuangbin
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. Input Input consists of a series of piece descriptions. Each piece description consists of the following data: Output For each piece description, print a single line containing the string: Sample Input
Sample Output
Source Mid-Atlantic 2003 |
题意:
给出N个点,一个圆的半径和圆心坐标:
- 如果N个点构成的多边形不是凸多边形,输出:HOLE IS ILL-FORMED
- 如果N个点构成凸多边形,圆在凸多边形内,输出:PEG WILL FIT
- 如果N个点构成凸多边形,圆不在凸多边内,输出:PEG WILL NOT FIT
分析:
首先是判断给出了多边形是不是凸多边形。然后判断圆包含在凸多边形中。
一定要保证圆心在凸多边形里面,然后判断圆心到每条线段的距离要大于等于半径。
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;const double eps = 1e-8;
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
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;}//两直线相交求交点//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交//只有第一个值为2时,交点才有意义pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}
};//*判断线段相交
bool inter(Line l1,Line l2)
{returnmax(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)) <= 0 &&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}//两点距离
double dist(Point a,Point b)
{return sqrt((a-b)*(a-b));
}//判断凸多边形,允许共线边
//点的编号0~n-1,可以是顺时针和逆时针
bool isConvex(Point poly[],int n){bool s[3];memset(s,false,sizeof s);for(int i=0;i<n;i++){s[sgn( (poly[(i+1)%n]-poly[i])^(poly[(i+2)%n]-poly[i]) )+1]=true;if(s[0]&&s[2]) 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>=0&&t<=1){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;elseresult=L.e;}return result;
}//判断点在线段上
bool OnSeg(Point P,Line L)
{returnsgn((L.s-P)^(L.e-P)) == 0 &&sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 &&sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0;
}//*判断点在凸多边形内
//点形成一个凸包,而且按逆时针排序(如果是顺时针把里面的<0改为>0)
//点的编号:0~n-1
//返回值:
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inConvexPoly(Point a,Point p[],int n)
{for(int i = 0;i < n;i++){if(sgn((p[i]-a)^(p[(i+1)%n]-a)) < 0)return -1;else if(OnSeg(a,Line(p[i],p[(i+1)%n])))return 0;}return 1;
}//*判断点在任意多边形内
//射线法,poly[]的顶点数要大于等于3,点的编号0~n-1
//返回值
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inPoly(Point p,Point poly[],int n)
{int cnt;Line ray,side;cnt = 0;ray.s = p;ray.e.y = p.y;ray.e.x = -100000000000.0;//-INF,注意取值防止越界for(int i = 0;i < n;i++){side.s = poly[i];side.e = poly[(i+1)%n];if(OnSeg(p,side))return 0;//如果平行轴则不考虑if(sgn(side.s.y - side.e.y) == 0)continue;if(OnSeg(side.s,ray)){if(sgn(side.s.y - side.e.y) > 0)cnt++;}else if(OnSeg(side.e,ray)){if(sgn(side.e.y - side.s.y) > 0)cnt++;}else if(inter(ray,side))cnt++;}if(cnt % 2 == 1)return 1;else return -1;
}int n;
Point o;//圆心
double R;//半径
Point p[110];
int main()
{while(scanf("%d",&n)!=EOF){if(n<3) break;scanf("%lf%lf%lf",&R,&o.x,&o.y);for(int i=0;i<n;i++)p[i].input();if(!isConvex(p,n)){//不是凸多边形printf("HOLE IS ILL-FORMED\n");continue;}//圆心不在凸多边形内if(inPoly(o,p,n)<0){printf("PEG WILL NOT FIT\n");continue;}bool flag=false;for(int i=0;i<n;i++){if(sgn(dist(o,NearestPointToLineSeg(o,Line(p[i],p[(i+1)%n]))) -R ) <0 ){flag=true;break;}}if(flag) printf("PEG WILL NOT FIT\n");else printf("PEG WILL FIT\n");}return 0;
}
POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,点到线段距离,点在多边形内相关推荐
- POJ - 1584 A Round Peg in a Ground Hole(综合几何)
题目链接:点击查看 题目大意:给出n个点,以及一个圆心和半径,首先判断这n个点能否构成凸包,若能,继续判断圆是否在凸包内 题目分析:这个题目确实非常综合,考察了判断凸包问题,判断圆是否在凸包内,只要保 ...
- POJ 1584 A Round Peg in a Ground Hole(点到直线距离,圆与多边形相交,多边形是否为凸)...
题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部. 分3步: 1.判断是否是凸多边形 2.判断点是否在多边形内部 3.判断点到各边的距离是否大于等于半径 上代码: #in ...
- 【POJ1584】A Round Peg in a Ground Hole,第一次的计算几何
Time:2016.07.15 Author:xiaoyimi 转载注明出处谢谢 思路: 算是计算几何的第一个题吧 判断是否为凸多边形用相邻边(向量)的叉积判断 (要求叉积的符号相同) 向量a,b,若 ...
- 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments
题目来源:http://poj.org/problem?id=3304 分析: 题目大意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出 ...
- POJ 1584 计算几何 凸包
链接: http://poj.org/problem?id=1584 题意: 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个 ...
- poj 1584(凸包+点在凸多边形内+圆在凸多边形内)
题意: 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全在n边形内部. 解题思路: 1.判断该多边形是否是凸包,由于 ...
- poj 1039 Pipe (判断 直线和 线段 是否相交 并 求交点)
http://poj.org/problem?id=1039 题意:已知电缆是由一段段直的管道连接而成的,并知道这些管道的位置,问一束光从最左边射进来,你可以调节光入射的位置和角度,问最远能射到多远. ...
- Codeforces Round #376 (Div. 2) D. 80-th Level Archeology —— 差分法 + 线段扫描法
题目链接:http://codeforces.com/contest/731/problem/D D. 80-th Level Archeology time limit per test 2 sec ...
- Codeforces Round #686 (Div. 3) F. Array Partition(二分+线段树)
题意:一段区间,让你分割成三段,第一段取max,第二段取min,第三段取max.问你怎么分割这个区间. 题解: 三个区间我们可以用两个点将一段区间分成三段区间. 二分:我们首先找这个题有关的单调性,我 ...
最新文章
- mysql学习之旅-数据库自动备份-测试环境搭建
- Leetcode 210. 课程表 II 解题思路及C++实现
- 常见的原生javascript DOM操作
- Spring Cloud【Finchley】-15 查看Zuul的路由端点和过滤器
- 在 Kubernetes 上弹性深度学习训练利器 -- Elastic Training Operator
- leetcode(1)485——最大连续 1 的个数(C++)
- 把设备分享给每个Docker Container
- 个性化推荐认知之----数字化转型浪潮下,产品经理应如何重新认知个性化推荐?...
- butterfly配置 hexo_Hexo博客之butterfly主题优雅魔改系列(持续更新)
- python hdf5 —— h5py
- 【Python3之模块及包的导入】
- 分布式本质论:高吞吐、高可用、可扩展 (1)
- 第二篇:基于小米手机的,第三方recovery教学
- 电子签的背后江湖:腾讯、蚂蚁、字节跳动的较量
- 06 第五章 一阶逻辑等值演算与推理
- CSS指北——浮动(Floating)规则详解
- CAD矩形阵列应用与实战技巧
- 计算机图文混合排版教学设计,Word图文混排教学设计
- Mac Google浏览器出现:您目前无法访问 XX.XX.XX.XX,因为此网站发送了 Google Chrome 无法处理的杂乱凭据
- House of sprit一谈
热门文章
- 事务日志已满,原因为“ACTIVE_TRANSACTION”
- TCP/IP详解学习笔记-基本概念
- 面向对象三大特性 -- 继承,封装,多态
- LightOJ 1093 - Ghajini 线段树
- 在MAC系统的eclipse里打开android sdk manager
- delphi DLL动态链接库
- Linux下运行纯dos软件,在linux下运行dos软件(转)
- springboot actuator_Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行情况监控...
- 异步和同步区别是什么_一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步...
- java路线_2021年Java学习路线图—精心整理