题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内。
 
分析:判断凸多边形可以使用相邻的三个点叉积判断,因为不知道顺时针还是逆时针,所以叉积如果有有整数和负数,那么一定不是凸多边形(注意允许多多点在一条线段上)。判断圆在凸多边形首先要判断圆心是否在多边形内,如果在多边形内,再次判断圆心到达到变形每条边的最短距离,如果小于半径就是不合法。ps:一道好题,通过这个题学会了不少东西。
 
代码如下:
=======================================================================================================================================
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std; const int MAXN = 1e3+;
const double EPS = 1e-;
const double oo = 1e10+; struct Point
{
double x, y;
Point(double x=, double y=):x(x),y(y){}
Point operator - (const Point &tmp)const{
return Point(x-tmp.x, y-tmp.y);
}
double operator ^(const Point &tmp)const{
return x*tmp.y - y*tmp.x;
}
double operator *(const Point &tmp)const{
return x*tmp.x + y*tmp.y;
}
};
double Dist(Point a, Point b)
{///两点间的距离
return sqrt((a-b)*(a-b));
}
int Sign(double t)
{
if(t > EPS)return ;
if(fabs(t) < EPS)return ;
return -;///负数
}
struct Segment
{
Point S, E;
Segment(Point S=, Point E=):S(S), E(E){}
bool OnSeg(const Point &p)
{///点是否在线段上
if(Sign( (S-E)^(p-E) ) == )///共线
if(Sign( (p.x-S.x)*(p.x-E.x) ) <= )///位于线段的中间或者端点
if(Sign( (p.y-S.y)*(p.y-E.y) ) <= )
return true;
return false;
}
bool Inter(const Segment &tmp)
{///只考虑完全相交的情况
return Sign((S-E)^(tmp.S-E)) * Sign((S-E)^(tmp.E-E)) == -;
}
Point NearPoint(const Point &p)
{///点到线段最近的点
Point res;
double r = ((E-S)*(p-S)) / ((E-S)*(E-S)); if(r > EPS && (1.0 - r) > EPS )
{///点在线段的投影在线段上
res.x = S.x + r * (E.x-S.x);
res.y = S.y + r * (E.y-S.y);
}
else
{///求离最近的端点
if(Dist(p, S) < Dist(p, E))
res = S;
else
res = E;
} return res;
}
};
struct Poly
{
int N;
Point vertex[MAXN]; bool IsConvex()
{///判断是否是凸多边形,可以共线
int vis[] = {};
for(int i=; i<N; i++)
{///如果同时出现整数和负数,说明存在凹的
int k = Sign((vertex[(i+)%N]-vertex[i])^(vertex[(i+)%N]-vertex[i]));
vis[k+] = ; if(vis[] && vis[])
return false;
}
return true;
}
int InPoly(const Point &Q)
{///判断点Q是否在多边形内,射线法,奇数在内,偶数在外
///在圆上返回0, 圆外-1, 圆内 1
Segment ray(Point(-oo, Q.y), Q);///构造射线的最远处
int cnt=;///统计相交的边数 for(int i=; i<N; i++)
{
Segment edge(vertex[i], vertex[(i+)%N]); if(edge.OnSeg(Q) == true)
return ;///点在边上 if(ray.OnSeg(vertex[i]) == true)
{///如果相交连接点,那么取y值小的点
if(vertex[(i+)%N].y - vertex[i].y > EPS)
cnt++;
}
else if(ray.OnSeg(vertex[(i+)%N]) == true)
{
if(vertex[i].y - vertex[(i+)%N].y > EPS)
cnt++;
}
else if(ray.Inter(edge) && edge.Inter(ray))
cnt++;
} if(cnt % )
return ;
else
return -;
}
};
struct Circle
{
Point center;///圆心
double R;///半径
}; bool Find(Poly &a, Circle &c)
{///判断圆是否在多边形内
if(a.InPoly(c.center) == -)
return false;///如果圆心在多边形外面 for(int i=; i<a.N; i++)
{
Segment edge(a.vertex[i], a.vertex[(i+)%a.N]);
double len = Dist(c.center, edge.NearPoint(c.center)); if(Sign(len-c.R) < )
return false;
} return true;
} int main()
{
Poly a;///定义多边形
Circle c;///定义圆 while(scanf("%d", &a.N) != EOF && a.N > )
{
scanf("%lf%lf%lf", &c.R, &c.center.x, &c.center.y);
for(int i=; i<a.N; i++)
scanf("%lf%lf", &a.vertex[i].x, &a.vertex[i].y); if(a.IsConvex() == false)
printf("HOLE IS ILL-FORMED\n");
else if(Find(a, c) == false)
printf("PEG WILL NOT FIT\n");
else
printf("PEG WILL FIT\n");
} return ;
}

A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&判断点在多边形内&判断圆在多边形内)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

    首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...

  4. 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 ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. POJ 1584:A Round Peg in a Ground Hole

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5741   Acc ...

  9. POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

    http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...

随机推荐

  1. C#世界中的委托

    委托是C#最重要的特性之一,C#后面的所有特性基本都是建立在委托的基础上的. 1.C#委托是什么? 可以把C#的委托理解为函数的一个包装,它使得C#中的函数可以作为参数来被传递.如果你学过C++,可以 ...

  2. 平衡搜索树(三) B-Tree

    B树的简介 B 树是为了磁盘或其它存储设备而设计的一种多叉平衡查找树.与红黑树很相似,但在降低磁盘I/0操作方面要更好一些(树的深度较低).许多数据库系统都一般使用B树或者B树的各种变形结构.B树与红 ...

  3. PC110304/UVA850

    这题目WA了好几次,主要是我没有理解清楚No solution.这个情况. 如果在match原文做好了,基本map一下就能过了. 与原句match的条件就是: 1.出现了26个字母 2.该空格的地方要 ...

  4. (传智博客)tp开发第一天之tp执行流程分析笔记

    1.入口文件index.php 2.ThinkPHP/ThinkPHP.php require THINK_PATH.'Common/runtime.php'; 3.ThinkPHP/Common/r ...

  5. JavaScript 高阶函数 + generator生成器

    map/reduce map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x ...

  6. js 中对象--对象结构(原型链基础解析)

    对于本篇对于如何自定义对象.和对象相关的属性操作不了解的话,可以查我对这两篇博客.了解这两篇可以更容易理解本篇文章 用构造函数创建了一个对象  obj对象的本身创建了两个属性  x=1   ,y=2 ...

  7. PLSQL性能优化技巧

    1.理解执行计划1-1.什么是执行计划 oracle数据库在执行sql语句时,oracle的优化器会根据一定的规则确定sql语句的执行路径,以确保sql语句能以最优性能执行.在oracle数据库系统中 ...

  8. Linux 多用户和多用户边界

    1. 需求背景 2. 多用户的边界: 独立的工作目录 3. 多用户的边界:可操作/访问的资源 4. 多用户的边界: 可执行的操作 5. 多用户的特性标识: UID和GID -------------- ...

  9. asp.net中的<%%>形式的详细用法实例讲解

    asp.net中的代码分离模式我们肯定都不陌生,C#(或者其它语言)写的代码一般不会和设计语言HTML混在一起,但是有的时候也避免不了,这时就会在UI页面里用<%%>来绑定显示.绑定变量数 ...

  10. 12个Icon图标资源网站

    1.除了Icon以外,还有很多不错的UI设计素材. 地址:http://worldui.com/2.除了免费Icon资源下载以外,还提供Icon定制的付费服务.地址:http://dryicons.c ...