方法一:扫描法(使用于任意多边形)

通常情况下,当射线与多边形的交点个数是奇数时,Q在多边形内,是偶数时,Q在多边形外。

通常将射线设为水平向右,那么就有一些特殊情况值得考虑

1.射线与多边形的顶点相交,这是交点只能计算一个。

2.射线与多边形顶点的交点不应该被计算

3.射线与多边形的一条边重合,这条边应该被忽略

算法描述:首先,对于多边形的水平边不做考虑,其次,对于多边形的顶点和射线相交的情况,如果该顶点时其所属的边上纵坐标较大的顶点,则计数,否则忽略该点,最后,对于Q在多边形上的情形,直接判断Q是否属于多边形。

时间复杂度分析:O(n)

注意:点的输入必须有顺序,不是顺时针就是逆时针

附上代码:


#include<iostream>
#include<cstdio>using namespace std;const int maxn=110;
const double eps=1e-5;struct point{double x,y;
};
point poly[maxn];int n,q;bool onsegment(point pi,point pj,point Q)
{if((Q.x-pi.x)*(pj.y-pi.y)==(pj.x-pi.x)*(Q.y-pi.y)&&min(pi.x,pj.x)<=Q.x&&Q.x<=max(pi.x,pj.x)&&min(pi.y,pj.y)<=Q.y&&Q.y<=max(pi.y,pj.y)){return true;}else{return false;}
}bool insidepolygon(point p)
{int counter=0;double xinters;point p1,p2;p1=poly[0];for(int i=1;i<=n;i++){p2=poly[i%n];if(onsegment(p1,p2,p)){return true;}if(p.y>min(p1.y,p2.y)){if(p.y<=max(p1.y,p2.y)){if(p.x<=max(p1.x,p2.x)){if(p1.y!=p2.y){xinters=(p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;if(p1.x==p2.x||p.x<=xinters){counter++;}}}}}p1=p2;}if(counter%2==0){return false;}return true;
}int main()
{point p;scanf("%d%d",&n,&q);for(int i=0;i<n;i++){scanf("%lf%lf",&poly[i].x,&poly[i].y);}for(int i=0;i<q;i++){scanf("%lf%lf",&p.x,&p.y);if(insidepolygon(p)){printf("within\n");}else{printf("outside\n");}}return 0;
}

方法二:叉乘判别法(只适用于凸多边形)

设这个多边形的边数为n。选一条边作为1号边,然后按照顺时针或者逆时针给每条边编号,连接第i(i=1,2,3......,n)条边的第一个端点和要测试的点得到一个向量vi。连接第一个端点与第二个端点得到向量ui,都以第一个端点为起点,作叉积vi*ui,记录结果。除了第一条边以外,都与前一次运算得到的叉积作乘积。如果为正则继续判断,知道遍历所有边,若全部满足,则证明点在多边形内,否则,证明点在多边形外。

#include<iostream>
#include<cstdio>using namespace std;const int maxn=110;struct point{double x,y;
};
point poly[maxn];
int n,q;double multi(point p1,point p2,point p0)
{return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}bool isinside(point p)
{double pre,now;for(int i=0;i<n;i++){now=multi(p,poly[i],poly[(i+1)%n]);if(i>0){if(pre*now<0){return 0;}}pre=now;}return true;
}int main()
{scanf("%d%d",&n,&q);for(int i=0;i<n;i++){scanf("%lf%lf",&poly[i].x,&poly[i].y);}point p;for(int i=0;i<q;i++){scanf("%lf%lf",&p.x,&p.y);if(isinside(p)){printf("Yes\n");}else{printf("No\n");}}return 0;
}

方法三:角度和的判断法(适用于任意多边形)

对于平面多边形来说,连接多边形内点于多边形所有顶点所形成的所有角的角度在要求精度范围内应该等于360度,如果小于360度或者大于360度,则证明不在多边形中。

#include<iostream>
#include<cstdio>
#include<cmath>using namespace std;const int maxn=110;
const double pi=3.1415926;struct point{double x,y;
};
point poly[maxn];int n,q;double ang(double x1,double y1,double x2,double y2)
{double ans=x1*x2+y1*y2;double base=sqrt(x1*x1+y1*y1)*sqrt(x2*x2+y2*y2);ans/=base;return acos(ans);
}int inpolygon(point p)
{double angle=0;for(int i=0;i<n;i++){double x1=poly[i].x-p.x;double y1=poly[i].y-p.y;double x2=poly[(i+1)%n].x-p.x;double y2=poly[(i+1)%n].y-p.y;angle+=ang(x1,y1,x2,y2);}if(fabs(angle-2*pi)<0.000001){return true;}else{return false;}
}int main()
{scanf("%d%d",&n,&q);for(int i=0;i<n;i++){scanf("%lf%lf",&poly[i].x,&poly[i].y);}point p;for(int i=0;i<q;i++){scanf("%lf%lf",&p.x,&p.y);if(inpolygon(p)){printf("Yes\n");}else{printf("No\n");}}return 0;
}

判断点在多边形的内外相关推荐

  1. php 判断点在多边形内,PHP判断点是否在多边形区域内外

    PHP判断点是否在多边形区域内外: 根据数学知识的射线法,射线与几何多边形相交的点的个数为奇数则是在几何内部: 偶数在外部:/** * Created by PhpStorm. * function: ...

  2. 判断点在多边形内外的简单算法

    发信人: RovingCloud (寻找当年的OI感觉), 信区: ACMICPC 标  题: [原创]惊喜发现判断点在多边形内外的超简单算法 发信站: 逸仙时空 Yat-sen Channel (W ...

  3. php之判断点在多边形内的api

    1.判断点在多边形内的数学思想:以那个点为顶点,作任意单向射线,如果它与多边形交点个数为奇数个,那么那个点在多边形内,相关公式: <?php class AreaApi{//$area是一个多边 ...

  4. 辐角原理判断点和多边形的关系

    辐角判断点和多边形的关系 一.辐角原理 二.适用条件 三.算法效果 四.matlab代码实现 \qquad标题写的多边形,然而在现实情况中多边形只是该问题的一个子集:我们先讲点和连通域的关系,点和多边 ...

  5. 判断点集与多边形的位置关系

    判断点集与多边形的位置关系 点集与凸多边形 点集与一般性多边形 点集与凸多边形 点集或者是点与多边形位置关系无非就三种 点在多边形的内部 点在多边形的外部 点在多边形上 一般如果该多边形是凸的那么我们 ...

  6. 判断点与多边形的关系(1):向量积法

    判断点与多边形的关系,是计算几何的经典问题,点与多边形的关系可以分为:点在多边形内(inside).点在多边形外(outside)以及点在多边形的边上(onside)三种. 在图像处理系统中,如果通过 ...

  7. HDU1756(判断点在多边形内外)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1756 bool IsOnline(Point p,Segment s) /** 判断点p是否在线段s上 * ...

  8. opencv 判断点在多边形内外

    基于Python 和 OpenCV 画出多边形,以及判断某个点是不是在多边形内. 1.cv2.pointPolygonTest() 函数 函数定义:cv2.pointPolygonTest(conto ...

  9. 判断点在多边形内的算法(Winding Number详解)

    在计算几何中,判定点是否在多边形内,是个非常有趣的问题.通常有两种方法: 1.Crossing Number(交叉数) 它计算从点P开始的射线穿过多边形边界的次数.当"交叉数"是偶 ...

最新文章

  1. 马逊s3云存储接口_使用 Amazon S3 云服务轻松实现存储
  2. Netty : writeAndFlush的线程安全及并发问题
  3. 【C++深度剖析教程5】C++中类的静态成员函数
  4. 哪个行业既锻炼人又便于今后创业?
  5. 软件_视频rtmp,rmvb,h265区别
  6. Float,Double单双精度在线转换成二进制
  7. python添加重复元素_在Python 3.6中添加迭代时重复元素
  8. java生命之树_《Spring揭秘》.王福强.文字版.pdf
  9. SQL连接两张或多张表
  10. android sqlite SQLiteDatabase
  11. Mysql数据库读写分离的实现
  12. 苹果手机来电归属地_手机号码归属地能否取消?
  13. C#屏蔽Alt+F4组合键
  14. 地磁基本知识(二)地磁异常
  15. 《数据时代 2025》报告-2017年版
  16. Java调整图片大小合并PNG图片生成ICON(保持背景透明)
  17. android绿豆通讯录xml,Android 数据库(SQLite)【简介、创建、使用(增删改查、事务、实战演练)、数据显示控件(ListView、Adapter、实战演练)】...
  18. 食品的英语名称总结-----实用
  19. brother printer 打印机 winform 小工具
  20. binlog数据库不写入binlog_mysql在不开启binlog的情况下导出数据库

热门文章

  1. CTP: SimNow , 策略模拟交易利器,赞!
  2. Proteus Design Suite v8.4 SP0 1CD PCB设计软件带高级模拟仿
  3. Validform表单验证时可以为空,否则按照指定的格式验证
  4. 管理的核心是什么?这里有一套科学、高效的团队管理法则
  5. JavaScript进阶(九)
  6. 提前批联发科面试经历
  7. 【10.03】富士康(世界500强第22位) 嵌入式软件相关多岗位招聘 10-45k月薪 内推...
  8. ggplot报错 stat_count() can only have an x or y aesthetic
  9. Error: stat_count() can only have an x or y aesthetic Run `rlang::last_error()` to see where the err
  10. C++——NOIP2016普及组 t4——魔法阵