改进弧长法 判断点是否在多边形内 c#代码

 public class Coordinate 
    {

        /// <summary>
        /// 经度X
        /// </summary>
        public double X;

        /// <summary>
        /// 纬度Y
        /// </summary>
        public double Y;

        /// <summary>
        /// 所在象限,原点,坐标轴1,2,3,4
        /// 为0时当正号处理
        /// </summary>
        public int Quadrant
        {
            get
            {
                if (X >= 0)
                {
                    if (Y >= 0) return 1;
                    if (Y < 0) return 4;
                                  }
                if (X < 0)
                {
                    if (Y >= 0) return 2;
                    if (Y < 0) return 3;
                  
                }

               return 0;
            }
        }


    }

/// <summary>
/// 弧长法判断点是否在多边形内
/// 第一个是若P[i]的某个坐标为0时,一律当正号处理;第二点是若被测点和多边形的顶点重合时要特殊处理。
/// </summary>
/// <param name="p">多边形顶点集合,有序</param>
/// <param name="corrdinate">要判断的点</param>
/// <returns>是否在多边形内</returns>
/// <remarks>
/// </remarks>
public bool InPolygon(IList<Coordinate> p, Coordinate corrdinate)
{
foreach (var item in p)
{
item.Y = item.Y - corrdinate.Y;
item.X = item.X - corrdinate.X;
}
//移除相邻相同象限的
for (var i = p.Count - 2; i > 0; i--)
{
if (p[i - 1].Quadrant == p[i].Quadrant)
p.RemoveAt(i);
}

//最后一个和第一个点连,将第一个点加到最后
p.Add(p[0]);

var count = 0;
for (var i = 0; i <= p.Count - 2; i++)
{
if (p[i].X == 0 && p[i].Y == 0) return true;//顶点重合

var f = p[i].X * p[i + 1].Y - p[i].Y * p[i + 1].X;
if (f == 0) return true;//在边上,特殊情况,如边(3,0)-(-3,0)

var t = p[i + 1].Quadrant - p[i].Quadrant;
if (Math.Abs(t) == 2) t = f > 0 ? 2 : -2;
if (t == -3) t = 1;//4->1(1-4=-3) =1
if (t == 3) t = -1;//1->4(4-1=3)=-1
count += t;

}
if (Math.Abs(count) == 2) return true;//在边上
if (Math.Abs(count) == 4) return true;//在内部
if (count == 0) return false;//在外部
return false;
}

原文地址:https://www.cnblogs.com/tobase/p/3324244.html