POJ 1584 A Round Peg in a Ground Hole --判定点在形内形外形上
题意: 给一个圆和一个多边形,多边形点可能按顺时针给出,也可能按逆时针给出,先判断多边形是否为凸包,再判断圆是否在凸包内。
解法: 先判是否为凸包,沿着i=0~n,先得出初始方向dir,dir=1为逆时针,dir=-1为顺时针,然后如果后面有两个相邻的边叉积后得出旋转方向为nowdir,如果dir*nowdir < 0,说明方向逆转了,即出现了凹点,说明不是凸多边形。
然后判圆是否在多边形内: 先判圆心是否在多边形内,用环顾法,然后如果在之内,则依次判断圆心与每条凸包边的距离与半径的距离,如果所有的dis都大于等于R,说明圆在凸包内。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define pi acos(-1.0)
#define eps 1e-8
using namespace std; struct Point{
double x,y;
Point(double x=, double y=):x(x),y(y) {}
void input() { scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r) {}
Point point(double a) { return Point(c.x + cos(a)*r, c.y + sin(a)*r); }
void input() { scanf("%lf%lf%lf",&c.x,&c.y,&r); }
};
int dcmp(double x) {
if(x < -eps) return -;
if(x > eps) return ;
return ;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } double DistanceToSeg(Point P, Point A, Point B)
{
if(A == B) return Length(P-A);
Vector v1 = B-A, v2 = P-A, v3 = P-B;
if(dcmp(Dot(v1, v2)) < ) return Length(v2);
if(dcmp(Dot(v1, v3)) > ) return Length(v3);
return fabs(Cross(v1, v2)) / Length(v1);
}
//点是否在多边形内部
int CheckPointInPolygon(Point A,Point* p,int n){
double TotalAngle = 0.0;
for(int i=;i<n;i++) {
if(dcmp(Cross(p[i]-A,p[(i+)%n]-A)) >= ) TotalAngle += Angle(p[i]-A,p[(i+)%n]-A);
else TotalAngle -= Angle(p[i]-A,p[(i+)%n]-A);
}
if(dcmp(TotalAngle) == ) return ; //外部
else if(dcmp(fabs(TotalAngle)-*pi) == ) return ; //完全内部
else if(dcmp(fabs(TotalAngle)-pi) == ) return ; //边界上
else return ; //多边形顶点
}
//判断未知时针方向的多边形是否是凸包
bool CheckConvexHull(Point* p,int n){
int dir = ; //旋转方向
for(int i=;i<n;i++) {
int nowdir = dcmp(Cross(p[(i+)%n]-p[i],p[(i+)%n]-p[i]));
if(!dir) dir = nowdir;
if(dir*nowdir < ) return false; //非凸包
}
return true;
} Point p[]; int main()
{
int n,i,j;
Circle Peg;
while(scanf("%d",&n)!=EOF && n >= )
{
scanf("%lf",&Peg.r); Peg.c.input();
for(i=;i<n;i++) p[i].input();
if(!CheckConvexHull(p,n)) { puts("HOLE IS ILL-FORMED"); continue; }
if(CheckPointInPolygon(Peg.c,p,n))
{
for(i=;i<n;i++)
{
double dis = DistanceToSeg(Peg.c,p[i],p[(i+)%n]);
if(dcmp(dis-Peg.r) < ) break;
}
if(i == n) { puts("PEG WILL FIT"); continue; }
}
puts("PEG WILL NOT FIT");
}
return ;
}
参考文章: http://blog.csdn.net/lyy289065406/article/details/6648606
射线法:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define eps 1e-8
using namespace std;
struct Point{
double x,y;
Point(double x=, double y=):x(x),y(y) {}
void input() { scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r) {}
Point point(double a) { return Point(c.x + cos(a)*r, c.y + sin(a)*r); }
void input() { scanf("%lf%lf%lf",&c.x,&c.y,&r); }
};
int dcmp(double x) {
if(x < -eps) return -;
if(x > eps) return ;
return ;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
Vector VectorUnit(Vector x){ return x / Length(x);}
Vector Normal(Vector x) { return Point(-x.y, x.x) / Length(x);}
double angle(Vector v) { return atan2(v.y, v.x); } bool OnSegment(Point P, Point A, Point B) {
return dcmp(Cross(A-P,B-P)) == && dcmp(Dot(A-P,B-P)) <= ;
}
double DistanceToSeg(Point P, Point A, Point B)
{
if(A == B) return Length(P-A);
Vector v1 = B-A, v2 = P-A, v3 = P-B;
if(dcmp(Dot(v1, v2)) < ) return Length(v2);
if(dcmp(Dot(v1, v3)) > ) return Length(v3);
return fabs(Cross(v1, v2)) / Length(v1);
}
//判断未知时针方向的多边形是否是凸包
bool CheckConvexHull(Point* p,int n){
int dir = ; //旋转方向
for(int i=;i<n;i++) {
int nowdir = dcmp(Cross(p[(i+)%n]-p[i],p[(i+)%n]-p[i]));
if(!dir) dir = nowdir;
if(dir*nowdir < ) return false; //非凸包
}
return true;
}
int Ray_PointInPolygon(Point A,Point* p,int n) {
int wn = ;
for(int i=;i<n;i++) {
//if(OnSegment(A,p[i],p[(i+1)%n])) return -1; //边界
int k = dcmp(Cross(p[(i+)%n]-p[i], A-p[i]));
int d1 = dcmp(p[i].y-A.y);
int d2 = dcmp(p[(i+)%n].y-A.y);
if(k > && d1 <= && d2 > ) wn++;
if(k < && d2 <= && d1 > ) wn--;
}
if(wn) return ; //内部
return ; //外部
} Point p[]; int main()
{
int n,i,j;
Circle Peg;
while(scanf("%d",&n)!=EOF && n >= )
{
scanf("%lf",&Peg.r); Peg.c.input();
for(i=;i<n;i++) p[i].input();
if(!CheckConvexHull(p,n)) { puts("HOLE IS ILL-FORMED"); continue; }
if(Ray_PointInPolygon(Peg.c,p,n))
{
for(i=;i<n;i++)
{
double dis = DistanceToSeg(Peg.c,p[i],p[(i+)%n]);
if(dcmp(dis-Peg.r) < ) break;
}
if(i == n) { puts("PEG WILL FIT"); continue; }
}
puts("PEG WILL NOT FIT");
}
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【计算几何=_=你值得一虐】
链接: 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(判断凸多边形,点到线段距离,点在多边形内)
A Round Peg in a Ground Hole Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4438 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: 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 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...
- 简单几何(点的位置) 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 ...
随机推荐
- 【初窥javascript奥秘之事件机制】论“点透”与“鬼点击”
前言 最近好好的研究了一番移动设备的点击响应速度,期间不断的被自己坑,最后搞得焦头烂额,就是现在可能还有一些问题,但是过程中感觉自己成长不少, 最后居然感觉对javascript事件机制有了更好的认识 ...
- 【zepto学习笔记02】零碎点
前言 上次我们看了zepto的选择器方面的东西,其实zepto简单很大程度是因为他用了最新的检索器querySelectorAll,今天我们来学习下zepto的一些零碎点的地方吧,主要根据zepto官 ...
- Weinre调试移动端页面
Weinre是什么 如果我们做的是Cordova(phonegap)或其他hybird应用,当使用到原生功能时候(类似原生请求数据或页面切换时),没办法在PC chrome浏览器调试页面,一旦页面在手 ...
- H5移动端页面设计心得分享
去年JDC出了不少优秀的武媚娘…不,H5呢,大家都很拼,同时当然也积累了一些经验和教训,今天结合咱们的实战案例,从字体,排版,动效,音效,适配性,想法这几个方面好好聊一聊关于H5的设计,希望对同学们有 ...
- SharePoint 2013 使用 PowerShell 更新用户
在SharePoint开发中,经常会遇到网站部署,然而,当我们从开发环境,部署到正式环境以后,尤其是备份还原,所有用户组的用户,还依然是开发环境的,这时,我们就需要用PowerShell更新一下: P ...
- MyEclipse 2015免费在线公开课,2月5日开讲
MyEclipse 2015免费在线公开课,2月5日开讲,由MyEclipse官方高级PM Brian Fernandes 主讲. 主讲内容: 更好地支持javascript和技术模块 全新的REST ...
- mac jdk 6设置
新装的mac 系统10.10 ,jdk是1.8,因为一些工具要使用 jdk 6,以下是设置过程 查看版本 java -version 查看java是再哪:在/usr/bin/java whereis ...
- iOS Apple Pay
iOS 苹果支付 需要证书支持支付功能 targets 打开支付功能按钮 //ApplePay#import <PassKit/PassKit.h> ...
- Mac wifi已打开但尚未连接到网络
把网络偏好设置 里面的询问新网络 关闭了 然后 重启电脑 试一下 应该就可以了
- SQL速记
集合操作 WITH a AS ( SELECT 1 id UNION SELECT 2 ), b AS ( SELECT 1 id UNION SELECT 3 ) SELECT * FR ...