判断点是否在面

1、代码

 

using System;
using System.Collections.Generic;

namespace ToolClass
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Point> polygonData = new List<Point>
            {
                new Point
                {
                    X=0,
                    Y=0
                },
                 new Point
                {
                    X=1,
                    Y=0
                },
                new Point
                {
                    X=0,
                    Y=1
                },
                new Point
                {
                    X=0,
                    Y=0
                },
            };
            Point testPoint1 = new Point
            {
                X = 0.2,
                Y = 0.2
            };
            Point testPoint2 = new Point
            {
                X = 0.9,
                Y = 0.1
            };
            if (IsPolygon(polygonData))
            {
                Console.WriteLine("结果一:" + IsPointInPolygon(GetPolygonToLines(polygonData), testPoint1));
                Console.WriteLine("结果二:" + IsPointInPolygon(GetPolygonToLines(polygonData), testPoint2));
            }
            else
            {
                Console.WriteLine("面数据异常");
            }
        
            Console.ReadKey();    
        }

        /// <summary>
        /// 判断点是否在面
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static bool IsPointInPolygon(List<Line> lines, Point point)
        {

            var count = 0;
            foreach (var item in lines)
            {
                if (point.Y < item.StartY != point.Y < item.EndY)
                    if (point.X < (point.Y - item.StartY) * (item.EndX - item.StartX) / (item.EndY - item.StartY) + item.StartX)
                        count++;
            }
            if ((count + 1) % 2 == 0)
                return true;
            else
                return false;
        }

        /// <summary>
        /// 面转线
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public static List<Line> GetPolygonToLines(List<Point> points)
        {
            List<Line> lines = new List<Line>();
            for (int i = 0; i < points.Count; i++)
            {
                Line line = new Line();
                line.StartX = points[i].X;
                line.StartY = points[i].Y;
                if (i == points.Count-1)
                {
                    line.EndX = points[0].X;
                    line.EndX = points[0].Y;
                }
                else
                {
                    line.EndX = points[i + 1].X;
                    line.EndY = points[i + 1].Y;
                }
                lines.Add(line);
            }
            return lines;
        }

        /// <summary>
        /// 判断是否是个面数据
        /// </summary>
        /// <param name="polygonData"></param>
        /// <returns></returns>
        public static bool IsPolygon(List<Point> polygonData)
        {
            var pointCount = polygonData.Count;
            if (pointCount < 3)
                return false;
            if (polygonData[0].X != polygonData[pointCount - 1].X || polygonData[0].Y != polygonData[pointCount - 1].Y)
                return true;
            return false;
        }

        public class Point
        {
            public double X { get; set; }
            public double Y { get; set; }
        }
        public class Line
        {
            public double StartX { get; set; }
            public double StartY { get; set; }
            public double EndX { get; set; }
            public double EndY { get; set; }
        }
    }
}

 

2、注释事项

  一些特殊情况未处理,比如在面得边线上

 

posted @ 2021-03-31 23:16  小七要走  阅读(258)  评论(0编辑  收藏  举报