美文网首页
.NET 判断一个点是否在一个范围内

.NET 判断一个点是否在一个范围内

作者: jfwangncs | 来源:发表于2019-06-10 14:41 被阅读0次

    使用百度地图的时候,常常会用到判断一个点是否在一个多边形的范围内,该方法用到的是射线法,通过修改Javascrpit的代码过来的,射线法的意思就是从点出发和任意的一边的交叉点数为奇数则为在改区域内,参考文档http://erich.realtimerendering.com/ptinpoly/

    具体代码如下

     public class location
            {
                public string lat;
                public string lng;
            }
    
            public static bool isPointInPolygon(location point, List<location> pts)
            {
    
    
                //检查类型
                if (point == null || pts == null)
                    return false;
    
                var N = pts.Count;
                var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
                var intersectCount = 0;//cross points count of x 
                var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
                location p1, p2;//neighbour bound vertices
                var p = point; //测试点
                p1 = pts[0];//left vertex        
                for (var i = 1; i <= N; ++i)
                {//check all rays            
                    if (p.lat.Equals(p1.lat) && p.lng.Equals(p1.lng))
                    {
                        return boundOrVertex;//p is an vertex
                    }
    
                    p2 = pts[i % N];//right vertex            
                    if (double.Parse(p.lat) < Math.Min(double.Parse(p1.lat), double.Parse(p2.lat)) || double.Parse(p.lat) > Math.Max(double.Parse(p1.lat), double.Parse(p2.lat)))
                    {//ray is outside of our interests                
                        p1 = p2;
                        continue;//next ray left point
                    }
    
                    if (double.Parse(p.lat) > Math.Min(double.Parse(p1.lat), double.Parse(p2.lat)) && double.Parse(p.lat) < Math.Max(double.Parse(p1.lat), double.Parse(p2.lat)))
                    {//ray is crossing over by the algorithm (common part of)
                        if (double.Parse(p.lng) <= Math.Max(double.Parse(p1.lng), double.Parse(p2.lng)))
                        {//x is before of ray                    
                            if (double.Parse(p1.lat) == double.Parse(p2.lat) && double.Parse(p.lng) >= Math.Min(double.Parse(p1.lng), double.Parse(p2.lng)))
                            {//overlies on a horizontal ray
                                return boundOrVertex;
                            }
    
                            if (double.Parse(p1.lng) == double.Parse(p2.lng))
                            {//ray is vertical                        
                                if (double.Parse(p1.lng) == double.Parse(p.lng))
                                {//overlies on a vertical ray
                                    return boundOrVertex;
                                }
                                else
                                {//before ray
                                    ++intersectCount;
                                }
                            }
                            else
                            {//cross point on the left side                        
                                var xinters = (double.Parse(p.lat) - double.Parse(p1.lat)) * (double.Parse(p2.lng) - double.Parse(p1.lng)) / (double.Parse(p2.lat) - double.Parse(p1.lat)) + double.Parse(p1.lng);//cross point of lng                        
                                if (Math.Abs(double.Parse(p.lng) - xinters) < precision)
                                {//overlies on a ray
                                    return boundOrVertex;
                                }
    
                                if (double.Parse(p.lng) < xinters)
                                {//before ray
                                    ++intersectCount;
                                }
                            }
                        }
                    }
                    else
                    {//special case when ray is crossing through the vertex                
                        if (p.lat == p2.lat && double.Parse(p.lng) <= double.Parse(p2.lng))
                        {//p crossing over p2                    
                            var p3 = pts[(i + 1) % N]; //next vertex                    
                            if (double.Parse(p.lat) >= Math.Min(double.Parse(p1.lat), double.Parse(p3.lat)) && double.Parse(p.lat) <= Math.Max(double.Parse(p1.lat), double.Parse(p3.lat)))
                            {//p.lat lies between p1.lat & p3.lat
                                ++intersectCount;
                            }
                            else
                            {
                                intersectCount += 2;
                            }
                        }
                    }
                    p1 = p2;//next ray left point
                }
    
                if (intersectCount % 2 == 0)
                {//偶数在多边形外
                    return false;
                }
                else
                { //奇数在多边形内
                    return true;
                }
    
            }
    

    相关文章

      网友评论

          本文标题:.NET 判断一个点是否在一个范围内

          本文链接:https://www.haomeiwen.com/subject/bnzytctx.html