本文源自:http://alienryderflex.com/polygon/

© 1998,2006,2007 Darel Rex Finley.  This complete article, unmodified, may be freely distributed for educational purposes.

Visit the new page which adds spline curves to this technique!  Also visit the shortest-path-through-polygon page!

Figure 1

Figure 1 demonstrates a typical case of a severely concave polygon with 14 sides.  The red dot is a point which needs to be tested, to determine if it lies inside the polygon.

The solution is to compare each side of the polygon to the Y (vertical) coordinate of the test point, and compile a list of nodes, where each node is a point where one side crosses the Y threshold of the test point. In this example, eight sides of the polygon cross the Y threshold, while the other six sides do not.  Then, if there are an odd number of nodes on each side of the test point, then it is inside the polygon; if there are an even number of nodes on each side of the test point, then it is outside the polygon.  In our example, there are five nodes to the left of the test point, and three nodes to the right.  Since five and three are odd numbers, our test point is inside the polygon.

(Note:  This algorithm does not care whether the polygon is traced in clockwise or counterclockwise fashion.)

Figure 2

Figure 2 shows what happens if the polygon crosses itself.  In this example, a ten-sided polygon has lines which cross each other.  The effect is much like “exclusive or,” or XOR as it is known to assembly-language programmers.  The portions of the polygon which overlap cancel each other out.  So, the test point is outside the polygon, as indicated by the even number of nodes (two and two) on either side of it.

Figure 3

In Figure 3, the six-sided polygon does not overlap itself, but it does have lines that cross.  This is not a problem; the algorithm still works fine.

Figure 4

Figure 4 demonstrates the problem that results when a vertex of the polygon falls directly on the Y threshold.  Since sides a and b both touch the threshold, should they both generate a node?  No, because then there would be two nodes on each side of the test point and so the test would say it was outside of the polygon, when it clearly is not!

The solution to this situation is simple.  Points which are exactly on the Y threshold must be considered to belong to one side of the threshold.  Let’s say we arbitrarily decide that points on the Y threshold will belong to the “above” side of the threshold.  Then, side a generates a node, since it has one endpoint below the threshold and its other endpoint on-or-above the threshold.  Side bdoes not generate a node, because both of its endpoints are on-or-above the threshold, so it is not considered to be a threshold-crossing side.

Figure 5

Figure 5 shows the case of a polygon in which one of its sides lies entirely on the threshold.  Simply follow the rule as described concerning Figure 4.  Side c generates a node, because it has one endpoint below the threshold, and its other endpoint on-or-above the threshold.  Side d does not generate a node, because it has both endpoints on-or-above the threshold.  And side e also does not generate a node, because it has both endpoints on-or-above the threshold.

Figure 6

Figure 6 illustrates a special case brought to my attention by John David Munch of Cal Poly.  One interior angle of the polygon just touches the Y-threshold of the test point.  This is OK.  In the upper picture, only one side (hilited in red) generates a node to the left of the test point, and in the bottom example, three sides do.  Either way, the number is odd, and the test point will be deemed inside the polygon.

Polygon Edge

If the test point is on the border of the polygon, this algorithm will deliver unpredictable results; i.e. the result may be “inside” or “outside” depending on arbitrary factors such as how the polygon is oriented with respect to the coordinate system.  (That is not generally a problem, since the edge of the polygon is infinitely thin anyway, and points that fall right on the edge can go either way without hurting the look of the polygon.)

C Code Sample

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.

bool pointInPolygon() {

int      i, j=polySides-1 ;
  boolean  oddNodes=NO      ;

for (i=0; i<polySides; i++) {
    if (polyY[i]<y && polyY[j]>=y
    ||  polyY[j]<y && polyY[i]>=y) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
        oddNodes=!oddNodes; }}
    j=i; }

return oddNodes; }

Here’s an efficiency improvement provided by Nathan Mercer.  The blue code eliminates calculations on sides that are entirely to the right of the test point.  Though this might be occasionally slower for some polygons, it is probably faster for most.

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.

bool pointInPolygon() {

int      i, j=polySides-1 ;
  boolean  oddNodes=NO      ;

for (i=0; i<polySides; i++) {
    if ((polyY[i]< y && polyY[j]>=y
    ||   polyY[j]< y && polyY[i]>=y)
    &&  (polyX[i]<=x || polyX[j]<=x)) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
        oddNodes=!oddNodes; }}
    j=i; }

return oddNodes; }

Here’s another efficiency improvement provided by Lascha Lagidse.  The inner “if” statement is eliminated and replaced with an exclusive-OR operation.

//  Globals which should be set before calling this function:
//
//  int    polySides  =  how many corners the polygon has
//  float  polyX[]    =  horizontal coordinates of corners
//  float  polyY[]    =  vertical coordinates of corners
//  float  x, y       =  point to be tested
//
//  (Globals are used in this example for purposes of speed.  Change as
//  desired.)
//
//  The function will return YES if the point x,y is inside the polygon, or
//  NO if it is not.  If the point is exactly on the edge of the polygon,
//  then the function may return YES or NO.
//
//  Note that division by zero is avoided because the division is protected
//  by the "if" clause which surrounds it.

bool pointInPolygon() {

int      i, j=polySides-1 ;
  boolean  oddNodes=NO      ;

for (i=0; i<polySides; i++) {
    if ((polyY[i]< y && polyY[j]>=y
    ||   polyY[j]< y && polyY[i]>=y)
    &&  (polyX[i]<=x || polyX[j]<=x)) {
      oddNodes^=(polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x); }
    j=i; }

return oddNodes; }

Integer Issue

What if you’re trying to make a polygon like the blue one below (Figure 7), but it comes out all horizontal and vertical lines, like the red one?  That indicates that you have defined some of your variables as integers instead of floating-point.  Check your code carefully to ensure that your test point and all the corners of your polygon are defined as, and passed as, floating-point numbers.

   Figure 7

转载于:https://www.cnblogs.com/shishm/archive/2012/05/03/2480680.html

点是否在面内算法(Point-In-Polygon Algorithm)相关推荐

  1. 点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部

    点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部: function isInPolygon(checkPoint, polygonPoints) {var counter = 0;var ...

  2. 算法介绍 | 泛洪算法(Flood fill Algorithm)

    算法别名: 漫水填充算法.种子填充算法(Seed Fill) 作用: 用于确定连接到多维数组中给定节点的区域,可以用来标记或者分离图像的一部分,实现如Ps中自动选区功能. 基本思想: 顾名思义就像洪水 ...

  3. 单目标应用:瞪羚优化算法(Gazelle Optimization Algorithm,GOA)优化BiLSTM权值和阈值(提供Matlab代码)

    瞪羚优化算法(Gazelle Optimization Algorithm,GOA)由Agushaka等人于2022年提出,该算法模拟了瞪羚逃避捕食者的行为,思路新颖,性能高效. 瞪羚的身高60-11 ...

  4. 机器学习中的数学——蓄水池抽样算法(Reservoir Sampling Algorithm)

    分类目录:<机器学习中的数学>总目录 蓄水池抽样算法(Reservoir Sampling Algorithm)解决了未知长度数据的均匀抽样问题,即:给定一个数据流,数据流长度NNN很大, ...

  5. 群体智能优化算法之鲸鱼优化算法(Whale Optimization Algorithm,WOA)

    获取更多资讯,赶快关注上面的公众号吧! 文章目录 鲸鱼优化算法(Whale Optimization Algorithm,WOA) 1.1 灵感 1.2 数学建模和优化算法 1.2.1 包围捕食(En ...

  6. 机器学习算法系列(五)- Lasso回归算法(Lasso Regression Algorithm)

    阅读本文需要的背景知识点:线性回归算法.一丢丢编程知识 最近笔者做了一个基于人工智能实现音乐转谱和人声分离功能的在线应用--反谱(Serocs),感兴趣的读者欢迎试用与分享,感谢您的支持!serocs ...

  7. EM算法(Expectation Maximization Algorithm)详解

    EM算法(Expectation Maximization Algorithm)详解 主要内容 EM算法简介 预备知识  极大似然估计 Jensen不等式 EM算法详解  问题描述 EM算法推导 EM ...

  8. 【转载】(EM算法)The EM Algorithm

    (EM算法)The EM Algorithm EM是我一直想深入学习的算法之一,第一次听说是在NLP课中的HMM那一节,为了解决HMM的参数估计问题,使用了EM算法.在之后的MT中的词对齐中也用到了. ...

  9. 感知哈希算法(Perceptual hash algorithm)的OpenCV实现

    1.前言 目前"以图搜图"的引擎越来越多,可参考博文: http://blog.csdn.net/forthcriminson/article/details/8698175 此篇 ...

  10. 维特比译码算法(Viterbi decoding algorithm)

    参考链接 卷积码译码之维特比译码算法(Viterbi decoding algorithm) (一)基本概念 1.经典通信系统 衡量译码器性能:译码后的错误概率 维特比译码是基于距离译码 (二)算法介 ...

最新文章

  1. ETL MySQL in Oracle ODI 12c
  2. 颜色传感器TCS230的使用
  3. mini2440 SD卡烧写系统
  4. 未来中国最受宠的人才
  5. IDEA修改module的名字
  6. C++入门经典-例7.8-const对象,标准尺寸
  7. PHP RSS/Feed 生成类库(支持RSS 1.0/2.0和ATOM)
  8. Linux:常用shell快捷键
  9. 敏捷开发生态系统系列之一:序言及需求管理生态(客户价值导向-可工作软件-响应变化)...
  10. 宗成庆统计自然语言处理第二版第13章读书笔记-文本分类与情感分类
  11. css如何实现div背景透明
  12. 前端性能优化之gzip 1
  13. 万字长文分析递归算法的时间和空间复杂度,从此对递归不再迷茫!
  14. 如何禁用C-State功能?关闭intel CPU的C-State省电模式方法
  15. 开源项目智慧教室:考试作弊系统、动态点名等功能
  16. buaacoding C.真心话大冒险
  17. 吴恩达:回顾2021,这些大事件影响了AI这一年
  18. 基于SSH的客户关系CRM管理系统设计与实现
  19. WIN10与XP共享连接打印机
  20. 紧急救援 dijkstra

热门文章

  1. vb mysql 字符串转日期_VB常用函数表
  2. bgl 词典_器材屋 篇五十二:“哪里不会点哪里”的后时代——哪里不识扫哪里:科大讯飞扫描词典笔评测_点读机...
  3. python函数名字_Python每日3题-为什么函数名字可以当做参数用?
  4. 微型计算机硬件的最小配置包括,职中计算机应用基础第一章测试题及答案
  5. 第四讲、Linux常用命令
  6. Python-OpenCV 处理图像(五):图像中边界和轮廓检测
  7. 常用的绘图约定——提高绘图和读图的效率
  8. 聊聊Java的泛型及实现
  9. Caffe —— Deep learning in Practice 深度学习实践
  10. 偷梁换柱——揭开多态的面纱