zoukankan      html  css  js  c++  java
  • GPS经纬度判断是否在圆、多边形、矩形内

    class 点面关系
    {
    static void Main(string[] args)
    {
    //Vector2D point1 = new Vector2D(39.909209536859834, 116.3225715637207);//in
    Vector2D point1 = new Vector2D(39.901045, 116.415596);//out
    Vector2D cPoint = new Vector2D(39.909209536859834, 116.3225715637207);
    Console.WriteLine("点是否在圆内:" + 点是否在圆内(cPoint, 8000, point1));
    Console.WriteLine("点是否在圆内:" + 点是否在圆内(cPoint, new Vector2D(39.901045, 116.415596), point1));


    //Vector2D point2 = new Vector2D(39.924745, 116.379204);//in
    Vector2D point2 = new Vector2D(39.928695, 116.546059);//out
    Vector2D pointA = new Vector2D(39.913423004886866, 116.36890411376953);
    Vector2D pointB = new Vector2D(39.93450133090293, 116.38727188110351);
    Console.WriteLine("点是否在矩形内:" + 点是否在矩形内(pointA, pointB, point2));


    Vector2D point3 = new Vector2D(39.957649, 116.376801);//in
    //Vector2D point3 = new Vector2D(39.919216, 116.2817);//out
    List<Vector2D> polygon = new List<Vector2D>();
    polygon.Add(new Vector2D(39.909209536859834, 116.3225715637207));
    polygon.Add(new Vector2D(39.95920953685983, 116.3725715637207));
    polygon.Add(new Vector2D(39.95920953685983, 116.42257156372072));
    polygon.Add(new Vector2D(39.909209536859834, 116.4725715637207));
    polygon.Add(new Vector2D(39.85920953685984, 116.42257156372072));
    polygon.Add(new Vector2D(39.85920953685984, 116.3725715637207));
    Console.WriteLine("点是否在多边形内:" + 点是否在多边形内(point3, polygon));

    Console.ReadLine();
    }

    /// <summary>
    /// 点是否在圆内(在边上也认为在圆内)
    /// </summary>
    /// <param name="cPoint">圆心坐标</param>
    /// <param name="cRadius">圆半径</param>
    /// <param name="point">当前点</param>
    /// <returns></returns>
    public static bool 点是否在圆内(Vector2D cPoint, double cRadius, Vector2D point)
    {
    var d1 = Distance(cPoint.Lat, cPoint.Lon, point.Lat, point.Lon);
    double distance = Math.Sqrt(Math.Pow(Math.Abs(point.X - cPoint.X), 2) + Math.Pow(Math.Abs(point.Y - cPoint.Y), 2));
    return distance <= cRadius;
    }

    private static double Distance(double lon1, double lat1, double lon2, double lat2)
    {
    double R = 6378137; //地球半径
    lat1 = lat1 * Math.PI / 180.0;
    lat2 = lat2 * Math.PI / 180.0;
    double sa2 = Math.Sin((lat1 - lat2) / 2.0);
    double sb2 = Math.Sin(((lon1 - lon2) * Math.PI / 180.0) / 2.0);
    return 2 * R * Math.Asin(Math.Sqrt(sa2 * sa2 + Math.Cos(lat1) * Math.Cos(lat2) * sb2 * sb2));
    }

    /// <summary>
    /// 点是否在圆内(在边上也认为在圆内)
    /// </summary>
    /// <param name="cPoint">圆心坐标</param>
    /// <param name="onPoint">圆边上坐标</param>
    /// <param name="point">当前点</param>
    /// <returns></returns>
    public static bool 点是否在圆内(Vector2D cPoint, Vector2D onPoint, Vector2D point)
    {
    double cRadius = Distance(cPoint.Lat, cPoint.Lon, onPoint.Lat, onPoint.Lon);
    double distance = Distance(cPoint.Lat, cPoint.Lon, point.Lat, point.Lon);
    return distance <= cRadius;
    }

    /// <summary>
    /// 点是否在多边形内(在边上也认为在多边形内)
    /// </summary>
    /// <param name="point">当前点</param>
    /// <param name="polygon">多边形点</param>
    /// <returns></returns>
    public static bool 点是否在多边形内(Vector2D point, List<Vector2D> polygon)
    {
    var res = SMath.CalcPointPolygonRelation(point, polygon);
    return res != PointPolygonRelation.OutOfPolygon;
    }

    /// <summary>
    /// 点是否在矩形内
    /// </summary>
    /// <param name="pointA">对角上点A</param>
    /// <param name="pointB">对角上点B</param>
    /// <param name="point">当前点</param>
    /// <returns></returns>
    public static bool 点是否在矩形内(Vector2D pointA, Vector2D pointB, Vector2D point)
    {
    List<Vector2D> polygon = new List<Vector2D>();
    polygon.Add(pointA);
    polygon.Add(new Vector2D(pointA.X, pointB.Y));
    polygon.Add(pointB);
    polygon.Add(new Vector2D(pointB.X, pointA.Y));
    var res = SMath.CalcPointPolygonRelation(point, polygon);
    return res != PointPolygonRelation.OutOfPolygon;
    }
    }

    ******************

    public static PointPolygonRelation CalcPointPolygonRelation(double x, double y, IList polygon)
    {
    if(polygon.Count < 3) return PointPolygonRelation.OutOfPolygon;
    IVector start = (IVector)polygon[polygon.Count - 2];
    if(start == null) return PointPolygonRelation.OutOfPolygon;
    IVector middle = (IVector)polygon[polygon.Count - 1];
    IVector end;
    PointPolygonRelation result = PointPolygonRelation.OutOfPolygon;
    int num = 0;
    double minX, minY, maxX, maxY;
    for(int i = 0; i < polygon.Count; i++, start = middle, middle = end)
    {
    end = (IVector)polygon[i];
    //如果点刚好在顶点上,则直接返回
    if((x == start.X && y == start.Y) || (x == middle.X && y == middle.Y) || (x == end.X && y == end.Y))
    {
    result = PointPolygonRelation.OnPolygonVertex;
    goto Return;
    }
    if(middle.X == end.X && middle.Y == end.Y)
    {
    continue;
    }
    minX = Math.Min(middle.X, end.X);
    maxX = Math.Max(middle.X, end.X);
    //如果X不落在最大X值和最小X值之间,则跳过
    if(x > maxX || x < minX) continue;

    minY = Math.Min(middle.Y, end.Y);
    maxY = Math.Max(middle.Y, end.Y);
    //如果Y大于最大Y值则跳过,因为向上做射线不可能相交
    if(y > maxY) continue;
    if(minX == maxX)//需要判断相交的线段为Y轴平行线
    {
    if(y > minY && y < maxY)
    {
    result = PointPolygonRelation.OnPolygonBorder;
    goto Return;
    }
    else if(y < minY)//如果在最小的Y之下,因为目标线段为Y轴平行线,所以记为1次
    {
    num++;
    }
    }
    else
    {
    double k = (middle.Y - end.Y) / (middle.X - end.X);
    double b = middle.Y - k * middle.X;

    double crossY = k * x + b;

    if(crossY < y) continue;//如果交点小于y则跳过,因为我们是向上做射线

    if(crossY == y)
    {
    result = PointPolygonRelation.OnPolygonBorder;
    goto Return;
    }

    if(x == maxX || x == minX)
    {
    if((start.X > middle.X && end.X < middle.X) || (start.X < middle.X && end.X > middle.X))
    num++;
    }
    else
    {
    num++;
    }
    }
    }

    if(num % 2 != 0) result = PointPolygonRelation.InPolygon;
    Return:

    return result;
    }

    /// <summary>
    /// 计算点和面的关系
    /// </summary>
    /// <param name="point"></param>
    /// <param name="polygon"></param>
    /// <returns></returns>
    public static PointPolygonRelation CalcPointPolygonRelation(IVector point, IList polygon)
    {
    return CalcPointPolygonRelation(point.X, point.Y, polygon);
    }

    _____________

    public enum PointPolygonRelation
    {
    /// <summary>
    /// 点在面内
    /// </summary>
    InPolygon,
    /// <summary>
    /// 点在边上
    /// </summary>
    OnPolygonBorder,
    /// <summary>
    /// 点在面外
    /// </summary>
    OutOfPolygon,
    /// <summary>
    /// 点在面的拐点上
    /// </summary>
    OnPolygonVertex
    }

  • 相关阅读:
    UVa OJ 148 Anagram checker (回文构词检测)
    UVa OJ 134 LoglanA Logical Language (Loglan逻辑语言)
    平面内两条线段的位置关系(相交)判定与交点求解
    UVa OJ 130 Roman Roulette (罗马轮盘赌)
    UVa OJ 135 No Rectangles (没有矩形)
    混合函数继承方式构造函数
    html5基础(第一天)
    js中substr,substring,indexOf,lastIndexOf,split等的用法
    css的textindent属性实现段落第一行缩进
    普通的css普通的描边字
  • 原文地址:https://www.cnblogs.com/94cool/p/2946030.html
Copyright © 2011-2022 走看看