zoukankan      html  css  js  c++  java
  • 判断一个点是否在一个多边形内

    /** 
     * 判断点是否在多边形内 
     * @param point 检测点 
     * @param pts   多边形的顶点 
     * @return      点在多边形内返回true,否则返回false 
     */  
    public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){  
          
        int N = pts.size();  
        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true  
        int intersectCount = 0;//cross points count of x   
        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差  
        Point2D.Double p1, p2;//neighbour bound vertices  
        Point2D.Double p = point; //当前点  
          
        p1 = pts.get(0);//left vertex          
        for(int i = 1; i <= N; ++i){//check all rays              
            if(p.equals(p1)){  
                return boundOrVertex;//p is an vertex  
            }  
              
            p2 = pts.get(i % N);//right vertex              
            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests                  
                p1 = p2;   
                continue;//next ray left point  
            }  
              
            if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of)  
                if(p.y <= Math.max(p1.y, p2.y)){//x is before of ray                      
                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal ray  
                        return boundOrVertex;  
                    }  
                      
                    if(p1.y == p2.y){//ray is vertical                          
                        if(p1.y == p.y){//overlies on a vertical ray  
                            return boundOrVertex;  
                        }else{//before ray  
                            ++intersectCount;  
                        }   
                    }else{//cross point on the left side                          
                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y                          
                        if(Math.abs(p.y - xinters) < precision){//overlies on a ray  
                            return boundOrVertex;  
                        }  
                          
                        if(p.y < xinters){//before ray  
                            ++intersectCount;  
                        }   
                    }  
                }  
            }else{//special case when ray is crossing through the vertex                  
                if(p.x == p2.x && p.y <= p2.y){//p crossing over p2                      
                    Point2D.Double p3 = pts.get((i+1) % N); //next vertex                      
                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x  
                        ++intersectCount;  
                    }else{  
                        intersectCount += 2;  
                    }  
                }  
            }              
            p1 = p2;//next ray left point  
        }  
          
        if(intersectCount % 2 == 0){//偶数在多边形外  
            return false;  
        } else { //奇数在多边形内  
            return true;  
        }  
          
    }  

    测试:

    // 测试一个点是否在多边形内  
    public static void main(String[] args) {  
          
        Point2D.Double point = new Point2D.Double(116.404072, 39.916605);  
          
        List<Point2D.Double> pts = new ArrayList<Point2D.Double>();  
        pts.add(new Point2D.Double(116.395, 39.910));  
        pts.add(new Point2D.Double(116.394, 39.914));  
        pts.add(new Point2D.Double(116.403, 39.920));  
        pts.add(new Point2D.Double(116.402, 39.914));  
        pts.add(new Point2D.Double(116.410, 39.913));  
          
        if(IsPtInPoly(point, pts)){  
            System.out.println("点在多边形内");  
        }else{  
            System.out.println("点在多边形外");  
        }  
    }  
  • 相关阅读:
    sqlserver数据库的备份与还原——完整备份与还原
    sqlserver中为节约存储空间的收缩数据库机制
    sqlserver数据库的分离与附加
    sqlserver的数据库状态——脱机与联机
    sqlserver打开对象资源管理器管理的帮助文档的快捷键
    sqlserver使用SQL语句创建数据库登录对象、数据库用户以及对为该用户赋予操作权限
    sqlserver window身份验证时切换账户的快捷键
    向现有数据库中添加文件组和数据文件
    使用SQL语句创建数据库2——创建多个数据库文件和多个日志文件
    Java中怎样判断一个字符串是否是数字?
  • 原文地址:https://www.cnblogs.com/-strong/p/8717704.html
Copyright © 2011-2022 走看看