• 判断点是否在面


    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、注释事项

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

  • 相关阅读:
    Medication Reconciliation Overview
    The Info-Button Standard: Bring Meaningful Use To the Patient
    Configuring Time in Windows 7 and Win 200
    oracle补齐日期
    mysql-proxy
    Oracle:Authid Current_User的使用
    oracle的sqlldr常见问题
    hive的select重命名字段显示成中文
    python访问hive
    禁用SSL v2.0、SSL v3.0协议
  • 原文地址:https://www.cnblogs.com/xiaoqiyaozou/p/14604351.html
Copyright © 2020-2023  润新知