电子围栏算法工具类-判断点与圆形,多边形关系



import java.awt.geom.Point2D;
import java.util.List;

/**
 * TestCUtil
 */
public class TestCUtil {
    /**
     * 地球半径
     */
    private static double earth = 6378138.0;
    /**
     *
     * @param d	d
     * @return double
     */
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 计算是否在圆上(单位/千米)
     * @param radius	半径
     * @param lat1		纬度
     * @param lng1		经度
     * @param lat2		纬度
     * @param lng2		经度
     * @return boolean
     */
    public static boolean isInCircle(double radius, double lat1, double lng1, double lat2, double lng2) {

        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 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)));
        s = s * earth;
        s = (double) Math.round(s * 10000) / 10000;
        if (s > radius) {
            //不在圆上
            return false;
        }
        return true;

    }

    /**
     * 判断点是否在多边形内
     * @param polygon	多边形
     * @param point		检测点
     * @return			点在多边形内返回true,否则返回false
     */
    public static boolean isPtInPoly(List<Point2D.Double> polygon, Point2D.Double point) {

        int n = polygon.size();
        boolean boundOrVertex = true;//如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
        int intersectCount = 0;//cross points count of x--交叉点计数X
        double precision = 2e-10;//浮点类型计算时候与0比较时候的容差
        Point2D.Double p1;
        Point2D.Double p2;
        Point2D.Double p = point;//当前点

        p1 = polygon.get(0);//left vertex--左顶点
        for (int i = 1; i <= n; ++i) {
            //check all rays--检查所有射线
            if (p.equals(p1)) {
                return boundOrVertex;//p is an vertex--p是一个顶点
            }
            p2 = polygon.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--x在射线之前
                    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--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--p交叉p2
                    Point2D.Double p3 = polygon.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--p.x在p1.x和p3.x之间
                        ++intersectCount;
                    } else {
                        intersectCount +=  2;
                    }
                }
            }
            p1 = p2;//next ray left point--下一条射线的左边点
        }
        if (intersectCount % 2 == 0) {
            //偶数在多边形外
            return false;
        }
        return true;
    }
    /**
     * testc
     * @param c c
     * @return 返回值
     */
    public String testc(String c) {
        return c + "c";
    }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值