package org.yzh.commons.util; 
 | 
  
 | 
/** 
 | 
 * 几何图形工具类 
 | 
 * @author yezhihao 
 | 
 * https://gitee.com/yezhihao/jt808-server 
 | 
 */ 
 | 
public class GeomUtils { 
 | 
  
 | 
    /** 长半轴(赤道半径,单位米,WGS-84) */ 
 | 
    public static final double A = 6378137; 
 | 
  
 | 
    /** 弧度 */ 
 | 
    public static final double RADIAN = Math.PI / 180.0; 
 | 
  
 | 
    /** 计算球面点到点距离(单位米) */ 
 | 
    public static double distance(double lng1, double lat1, double lng2, double lat2) { 
 | 
        double radLat1 = lat1 * RADIAN; 
 | 
        double radLat2 = lat2 * RADIAN; 
 | 
        double a = radLat1 - radLat2; 
 | 
        double b = lng1 * RADIAN - lng2 * RADIAN; 
 | 
  
 | 
        double distance = A * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); 
 | 
        distance = Math.round(distance * 10000) / 10000D; 
 | 
        return distance; 
 | 
    } 
 | 
  
 | 
    /** 计算平面点到点距离(单位米) */ 
 | 
    public static double distance_(double x1, double y1, double x2, double y2) { 
 | 
        double a = x1 - x2; 
 | 
        double b = y1 - y2; 
 | 
        double distance = Math.sqrt(Math.abs((a * a) + (b * b))); 
 | 
        return distance * 100000; 
 | 
    } 
 | 
  
 | 
    /** 计算点到线距离(单位米) */ 
 | 
    public static double distancePointToLine(double x1, double y1, double x2, double y2, double x0, double y0) { 
 | 
        double a = distance_(x1, y1, x2, y2); 
 | 
        double b = distance_(x1, y1, x0, y0); 
 | 
        double c = distance_(x2, y2, x0, y0); 
 | 
        if (c <= 0.001 || b <= 0.001) { 
 | 
            return 0.0; 
 | 
        } 
 | 
        if (a <= 0.001) { 
 | 
            return b; 
 | 
        } 
 | 
  
 | 
        double aa = a * a; 
 | 
        double bb = b * b; 
 | 
        double cc = c * c; 
 | 
        if (cc >= aa + bb) { 
 | 
            return b; 
 | 
        } 
 | 
        if (bb >= aa + cc) { 
 | 
            return c; 
 | 
        } 
 | 
        double p = (a + b + c) / 2D; 
 | 
        double s = Math.sqrt(p * (p - a) * (p - b) * (p - c)); 
 | 
        return 2D * s / a; 
 | 
    } 
 | 
  
 | 
    /** 判断坐标是否在矩形内 */ 
 | 
    public static boolean inside(double x, double y, double minX, double minY, double maxX, double maxY) { 
 | 
        return (x >= minX && x <= maxX && 
 | 
                y >= minY && y <= maxY); 
 | 
    } 
 | 
  
 | 
    /** 判断坐标是否在多边形内部 */ 
 | 
    public static boolean inside(double x, double y, double[] points) { 
 | 
        boolean oddNodes = false; 
 | 
  
 | 
        double ret; 
 | 
        for (int i = 0, j = points.length - 2; i < points.length; i += 2) { 
 | 
            double x1 = points[i]; 
 | 
            double y1 = points[i + 1]; 
 | 
            double x2 = points[j]; 
 | 
            double y2 = points[j + 1]; 
 | 
  
 | 
            if ((y1 < y && y2 >= y) || (y2 < y && y1 >= y)) { 
 | 
                ret = x1 + (y - y1) / (y2 - y1) * (x2 - x1); 
 | 
                if (ret < x) 
 | 
                    oddNodes = !oddNodes; 
 | 
            } 
 | 
            j = i; 
 | 
        } 
 | 
        return oddNodes; 
 | 
    } 
 | 
  
 | 
    /** 计算三个坐标角度 */ 
 | 
    public static double getDegree(double lng1, double lat1, double lng2, double lat2, double lng3, double lat3) { 
 | 
        return getRadian(lng1, lat1, lng2, lat2, lng3, lat3) * (180 / Math.PI); 
 | 
    } 
 | 
  
 | 
    /** 计算三个坐标弧度 */ 
 | 
    public static double getRadian(double lng1, double lat1, double lng2, double lat2, double lng3, double lat3) { 
 | 
        double[] p1 = ball2xyz(lng1, lat1); 
 | 
        double[] p2 = ball2xyz(lng2, lat2); 
 | 
        double[] p3 = ball2xyz(lng3, lat3); 
 | 
  
 | 
        double abx = p1[x] - p2[x]; 
 | 
        double aby = p1[y] - p2[y]; 
 | 
        double abz = p1[z] - p2[z]; 
 | 
  
 | 
        double cbx = p3[x] - p2[x]; 
 | 
        double cby = p3[y] - p2[y]; 
 | 
        double cbz = p3[z] - p2[z]; 
 | 
  
 | 
        double p1p2 = Math.sqrt(abx * abx + aby * aby + abz * abz); 
 | 
        double p2p3 = Math.sqrt(cbx * cbx + cby * cby + cbz * cbz); 
 | 
  
 | 
        double p = abx * cbx + aby * cby + abz * cbz; 
 | 
        double a = Math.acos(p / (p1p2 * p2p3)); 
 | 
  
 | 
        double c = abx * cby - cbx * aby; 
 | 
        return (c > 0) ? a : -a; 
 | 
    } 
 | 
  
 | 
    private static final int x = 0; 
 | 
    private static final int y = 1; 
 | 
    private static final int z = 2; 
 | 
  
 | 
    private static double[] ball2xyz(double lng, double lat) { 
 | 
        lat = lat * RADIAN; 
 | 
        lng = lng * RADIAN; 
 | 
  
 | 
        double[] p = new double[3]; 
 | 
  
 | 
        double t = Math.cos(lat) * 64; 
 | 
        p[x] = Math.cos(lng) * t; 
 | 
        p[y] = Math.sin(lng) * t; 
 | 
        p[z] = Math.sin(lat) * 64; 
 | 
        return p; 
 | 
    } 
 | 
} 
 |