LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1190
题意:给你一个多边形含有n个点;然后又m个查询,每次判断点(x, y)是否在多边形的内部;
射线法判断即可适用于任何(凸或凹)多边形;时间复杂度为O(n);
判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n);射线法可以正确用于凹多边形;
射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正确使用在凹多边形上,而且不需要考虑精度误差问题。该算法思想是从点出发向右水平做
一条射线,计算该射线与多边形的边的相交点个数,当点不在多边形边上时,如果是奇数,那么点就一定在多边形内部,否则,在外部。
/*
射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n);
射线法可以正确用于凹多边形;
射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正
确使用在凹多边形上,而且不需要考虑精度误差问题。该算法思想是从点出
发向右水平做一条射线,计算该射线与多边形的边的相交点个数,当点不在
多边形边上时,如果是奇数,那么点就一定在多边形内部,否则,在外部。
*/
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = ;
const double eps = 1e-;
const int INF = 0x3f3f3f3f;
//////////////////////////////////////////////////////////////////
struct point
{
double x, y;
point(double x=, double y=) : x(x), y(y){}
friend point operator - (const point& p1, const point& p2)
{
return point(p1.x-p2.x, p1.y-p2.y);
}
friend double operator ^ (const point& p1, const point& p2)
{
return p1.x*p2.y - p1.y*p2.x;
}
};
//////////////////////////////////////////////////////////////////
struct Segment
{
point s, e;
};
//////////////////////////////////////////////////////////////////
///判断一个double类型的数是 0 <0 >0;
int Sign(double x)
{
if( fabs(x) < eps )return ;
if(x > )return ;
return -;
}
//////////////////////////////////////////////////////////////////
///判断o在ab的哪边;0:o在直线ab上; >0:在左边; <0:在右边;
double cross(point o, point a, point b)
{
return ((a-o)^(b-o));
}
//////////////////////////////////////////////////////////////////
///已知abc三点在一条直线上,判断点a是否在线段bc之间;<=0:在 >0:不在;
int Between(point a, point b, point c)
{
if(fabs(b.x-c.x) > fabs(b.y-c.y))
return Sign(min(b.x, c.x)-a.x)*Sign(max(b.x, c.x)-a.x);
else
return Sign(min(b.y, c.y)-a.y)*Sign(max(b.y, c.y)-a.y);
}
//////////////////////////////////////////////////////////////////
///判断点p0和线段S上,<=0:在,1:不在;
int PointOnSegment(point p0, Segment S)
{
if(Sign(cross(S.s, S.e, p0)) == )
return Between(p0, S.s, S.e);
return ;
}
//////////////////////////////////////////////////////////////////
///求线段a和线段b的交点个数;
int SegmentCross(Segment a, Segment b)
{
double x1 = cross(a.s, a.e, b.s);
double x2 = cross(a.s, a.e, b.e);
double x3 = cross(b.s, b.e, a.s);
double x4 = cross(b.s, b.e, a.e); if(Sign(x1*x2)< && Sign(x3*x4)<) return ;
if((Sign(x1)== && Between(b.s, a.s, a.e)<=) ||
(Sign(x2)== && Between(b.e, a.s, a.e)<=) ||
(Sign(x3)== && Between(a.s, b.s, b.e)<=) ||
(Sign(x4)== && Between(a.e, b.s, b.e)<=))
return ;
return ;
}
//////////////////////////////////////////////////////////////////
///判断点p0与含有n个节点的多边形的位置关系,p数组是顶点集合;
///返回0:边上或顶点上, 1:外面, -1:里面;
int PointInPolygon(point p0, point p[], int n)
{
Segment L, S;
point temp;
L.s = p0, L.e = point(INF, p0.y);///以p0为起点的射线L; int counts = ;
p[n] = p[]; for(int i=; i<=n; i++)
{
S.s = p[i-], S.e = p[i]; if(PointOnSegment(p0, S) <= ) return ;
if(S.s.y == S.e.y) continue;///和射线平行; if(S.s.y > S.e.y) temp = S.s;
else temp = S.e; if(PointOnSegment(temp, L) == -)
counts ++;
else if(SegmentCross(L, S) == )
counts ++;
}
if(counts%) return -;
return ;
}
//////////////////////////////////////////////////////////////////
int main()
{
point p[N];
int T, tCase = , n, q;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i=; i<n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
scanf("%d", &q);
printf("Case %d:\n", tCase++);
for(int i=; i<=q; i++)
{
int x, y;
scanf("%d %d", &x, &y);
int ans = PointInPolygon(point(x, y), p, n);
if(ans == ) puts("No");
else puts("Yes");
}
}
return ;
}
LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)的更多相关文章
- Cupid's Arrow---hdu1756(判断点与多边形的位置关系 模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756 题意:中文题,套模板即可: /* 射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为 ...
- luogu 1355 神秘大三角 判断点和三角形的位置关系 面积法 叉积法
题目链接 题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三个顶点 第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系 (详见样 ...
- 叉积_判断点与三角形的位置关系 P1355 神秘大三角
题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三个顶点 第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系 (详见样例) 所有 ...
- ZOJ1081 Points Within 点和多边形的位置关系
ZOJ1081 给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外 在多边形外的点引一条射线必然穿过多边形的两条边 而在多边形内的点则不一定. 当然凹多边形有特殊情况 但是总能找到对应位置关 ...
- 判断两条直线的位置关系 POJ 1269 Intersecting Lines
两条直线可能有三种关系:1.共线 2.平行(不包括共线) 3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, ...
- POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置关系
POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置 Description Calculate the number of toys th ...
- POJ 2318 /// 判断点与直线的位置关系
题目大意: n块玩具箱隔板 m个玩具落地点 给定玩具箱的左上和右下两个端点 接下来给定n块隔板的上点的x和下点的x(因为y就是玩具箱的上下边缘) 接下来给定m个玩具落地点 输出n+1个区域各有的玩具数 ...
- Segments---poj3304(判断直线与线段的位置关系)
题目链接:http://poj.org/problem?id=3304 题意:给你n个线段,求是否有一条直线与所有的线段都相交,有Yes,没有No; 枚举所有的顶点作为直线的两点,然后判断这条直线是否 ...
- UVA 10256 The Great Divide (凸包,多边形的位置关系)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148 [思路] 凸包 求出红蓝点的凸包,剩下的问题就是判断两个凸 ...
随机推荐
- CentOS6.4 安装Nagios 并监控端口
1.下载所需文件nagios-3.4.3.tar.gz,nagios-plugins-1.4.15.tar.gz,nrpe-2.14.tar.gz,sendEmail-v1.56.tar.gz 下载地 ...
- 生成CSV文件后再将CSV文件导入到mysql
1.生成CSV jar包:http://pan.baidu.com/s/1xIL26 String csvFilePath = "d:\\test.csv"; CsvWriter ...
- pygame系列_原创百度随心听音乐播放器_完整版
程序名:PyMusic 解释:pygame+music 之前发布了自己写的小程序:百度随心听音乐播放器的一些效果图 你可以去到这里再次看看效果: pygame系列_百度随心听_完美的UI设计 这个程序 ...
- 一致性 hash 算法
consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在 cache 系统中应用越来越广泛: 1 ...
- ps插件安装
CutAndSliceMe.zxp 切图插件安装,下载后改为zip后缀,再解压后 复制文件夹到(PS软件安装目录)PhotoshopCC\Plug-ins\Panels文件夹下面
- shell.application asp多种组件执行cmd 单文件版本
<%@ Language="VBScript" %> <% ) theComponent() = "Scripting.FileSystemObject ...
- Net-Speeder为OpenVZ加速
VPS购买地址 1. net-speeder安装 wget https://coding.net/u/njzhenghao/p/download/git/raw/master/net_speeder- ...
- MyEclipse的注册过程
说在前面的话: 说到收费软件MyEclipse,大家可能对它又爱又恨,其实软件收钱也是为了有更好的发展,我们的建议是先试用,如果觉得不错,可以使用正版软件! 准备工作: 1.MyEclipse安装文件 ...
- jquery选中将select下拉框中一项后赋值给text文本框
jquery选中将select下拉框中一项后赋值给text文本框,出现无法将第一个下拉框的value赋值给文本框 因为select默认选中第一项..在选择第一项时,便导致无法激发onchange事件. ...
- PHP函数库(other)
PHP函数库(other) Session函数: session_abort — Discard session array changes and finish session session_ab ...