判断一个点是否在一个多边形里

“判断一个点是否在一个多边形里”,一开始以为是个挺难的问题,但Google了一下之后发现其实蛮简单,所用到的算法叫做“Ray-casting Algorithm”,中文应该叫“光线投射算法”,这是维基百科的描述:[维基百科]

简单地说可以这么判断:从这个点引出一根“射线”,与多边形的任意若干条边相交,累计相交的边的数目,如果是奇数,那么点就在多边形内,否则点就在多边形外。

如图,A点引一条射线,与多边形3条边相交,奇数,所以A点在多边形内,而从B点引一条射线,与多边形的2条边相交,偶数,所以B点在多边形外。

我打算把这个算法用于判断地图上所在的位置是否在一个范围之内,我先用鼠标在地图上绘制出一个多边形区域,然后再用这个方法判断一个坐标是否在这个多边形范围内,我仍然拿五角星做试验品,在高德地图上描出一个五角星:

嗯?怎么五角星居然中间没被镂空?这是怎么回事?经过研究,我发现高德地图的鼠标工具的多边形填充用的是另外一套规则,叫做“None Zero Mode”,判断一个点是否在多边形内的规则就变成了:从这个点引出一根“射线”,与多边形的任意若干条边相交,计数初始化为0,若相交处被多边形的边从左到右切过,计数+1,若相交处被多边形的边从右到左切过,计数-1,最后检查计数,如果是0,点在多边形外,如果非0,点在多边形内。回到五角星的例子,这次要注意多边形线条描绘的方向:

从C点引出一条射线,与这条射线相交的两条多边形的边均是从左向右切过,总计数是2,因此C点在多边形内。用个更形象点的方式描述就是:从C点出发,一直朝一个方向走,遇到两条单行道,都是从自己的左边切至右边的方向,计数+1,计数+1,总计数所以是2。

算法实现起来居然很简单,几行代码即可,真的是几行代码,我用的是C#,大家可以轻轻松松改成别的。

    public static class RayCastingAlgorithm {
        public static bool IsWithin(Point pt, IList<Point> polygon, bool noneZeroMode) {
            int ptNum = polygon.Count();
            if (ptNum < 3) {
                return false;
            }
            int j = ptNum - 1;
            bool oddNodes = false;
            int zeroState = 0;
            for (int k = 0; k < ptNum; k++) {
                Point ptK = polygon[k];
                Point ptJ = polygon[j];
                if (((ptK.Y > pt.Y) != (ptJ.Y > pt.Y)) && (pt.X < (ptJ.X - ptK.X) * (pt.Y - ptK.Y) / (ptJ.Y - ptK.Y) + ptK.X)) {
                    oddNodes = !oddNodes;
                    if (ptK.Y > ptJ.Y) {
                        zeroState++;
                    }
                    else {
                        zeroState--;
                    }
                }
                j = k;
            }
            return noneZeroMode?zeroState!=0:oddNodes;
        }
    }

我用WPF写了个demo,如图:

给懒得敲打吗的同学玩玩。(VS2015

时间: 2024-08-04 22:30:34

判断一个点是否在一个多边形里的相关文章

如何判断一个点是否在一个多边形内?

提示:对多边形进行分割,成为一个个三角形,判断点是否在三角形内. 一个非常有用的解析几何结论:如果P2(x1,y1),P2(x2,y2), P3(x3,y3)是平面上的3个点,那么三角形P1P2P3的面积等于下面绝对值的二分之一: | x1  y1  1 | | x2 y2  1 | = x1y2 + x3y1 + x2y3 –x3y2 – x2y1 – x1y3 | x3 y3  1 | 当且仅当点P3位于直线P1P2(有向直线P1->P2)的右侧时,该表达式的符号为正.这个公式可以在固定的时

js 判断一个点是否在一个多边形之内

出处: https://github.com/substack/point-in-polygon/blob/master/index.js github: https://github.com/substack/point-in-polygon module.exports = function (point, vs) { // ray-casting algorithm based on // http://www.ecse.rpi.edu/Homepages/wrf/Research/Sho

判断一个点是否在多边形内

#转载自:http://blog.csdn.net/u011722133/article/details/52813374 在GIS(地理信息管理系统)/PCL(点云库)中,判断一个坐标是否在多边形内部是个经常要遇到的问题.乍听起来还挺复杂.根据W. Randolph Franklin 提出的PNPoly算法,只需区区几行代码就解决了这个问题 假设多边形的坐标存放在一个数组里,首先我们需要取得该数组在横坐标和纵坐标的最大值和最小值,根据这四个点算出一个四边型,首先判断目标坐标点是否在这个四边型之

判断一个坐标是否在多边形内部

在GIS(地理信息管理系统)中,判断一个坐标是否在多边形内部是个经常要遇到的问题.乍听起来还挺复杂.根据W. Randolph Franklin 提出的PNPoly算法,只需区区几行代码就解决了这个问题. 假设多边形的坐标存放在一个数组里,首先我们需要取得该数组在横坐标和纵坐标的最大值和最小值,根据这四个点算出一个四边型,首先判断目标坐标点是否在这个四边型之内,如果在这个四边型之外,那可以跳过后面较为复杂的计算,直接返回false. if (p.x < minX || p.x > maxX |

js+jQuery判断一个点是否在多边形中

//* 计算一个点是否在多边形里 //* @param {Object} pt 标注点 例: pt = {"lat":30,"lng":40} //* @param {Object} poly 多边形数组 //例 poly = [{"lat":20,"lng":20},{"lat":40,"lng":40},{"lat":20,"lng":60}]

如何判断一个点是否在多边形内

原理 如何判断一个点在多边形内还是多边形外,最常见的方法就是射线法,原理就是,从点P开始,做一条任意的射线,如果射线与多边形边的交点个数为偶数个则表明点在多边形外,交点个数为奇数个时则表明点在多边形内.如果点在多边形内部时,无论如何画射线都会有交点,且为奇数个.如下图: 实现(C#) 1 public static bool InsidePolygon(List<Point> polygon, Point p) 2 { 3 if (polygon.Count <= 0) 4 return

python中如何不区分大小写的判断一个元素是否在一个列表中

python中判断某一个元素是否在一个列表中,可以使用关键字in 和 not in. 示例如下: 如果需要输出相应的信息,可以搭配使用if语句,这里不赘述. ------------------------------------------------------------------------------------------分割线------------------------------------------------------------------------------

点在多边形内算法,C#判断一个点是否在一个复杂多边形的内部

判断一点是否在不规则图像的内部算法,如下图是由一个个点组成的不规则图像,判断某一点是否在不规则矩形内部,先上效果图 算法实现如下,算法简单,亲试有效 public class PositionAlgorithmHelper { /// <summary> /// 判断当前位置是否在不规则形状里面 /// </summary> /// <param name="nvert">不规则形状的定点数</param> /// <param n

判断一个点是否在一个复杂多边形的内部

结论:从目标点出发引一条射线,看这条射线和多边形所有边的交点数目.如果有奇数个交点,则说明在内部,如果有偶数个交点,则说明在外部.利用此结论近些代码编写 1 // 功能:判断点是否在多边形内 2 // 方法:求解通过该点的水平线与多边形各边的交点 3 // 结论:单边交点为奇数,成立! 4 5 // 参数: 6 // POINT p 指定的某个点 7 // LPPOINT ptPolygon 多边形的各个顶点坐标(首末点可以不一致) 8 // int nCount 多边形定点的个数 9 10 p