C# 如何检查给定点是位于多边形内还是外(How to check if a given point lies inside or outside a polygon)

 给定一个多边形和一个点 ' p ',判断 ' p ' 是否位于多边形内部。位于边界上的点被视为内部。

例子:

方法:解决这个问题的思路是基于如何检查两个给定的线段是否相交,使用方法如下:

文章:
Javascript 如何检查两个给定的线段是否相交:Javascript 如何检查两个给定的线段是否相交(How to check if two given line segments intersect)_js判断两条线段是否相交-优快云博客

Java 如何检查两个给定的线段是否相交:Java 如何检查两个给定的线段是否相交(How to check if two given line segments intersect)_java判断两条线段是否相交-优快云博客

Python 如何检查两个给定的线段是否相交:Python 如何检查两个给定的线段是否相交(How to check if two given line segments intersect)_python如何判断两个线段相交-优快云博客

C# 如何检查两个给定的线段是否相交:C# 如何检查两个给定的线段是否相交(How to check if two given line segments intersect)_c# 线段交点-优快云博客

C++ 如何检查两个给定的线段是否相交:C++ 如何检查两个给定的线段是否相交(How to check if two given line segments intersect)_c++判断两条线段是否相交-优快云博客

方法:
1、在每个点的右侧画一条水平线,并延伸至无穷大

2、计算线与多边形边相交的次数。

3、如果交点数为奇数或点位于多边形的边缘,则该点位于多边形内部。如果任何条件都不成立,则该点位于多边形外部。

如何处理上图中的点‘g’? 

请注意,如果点位于给定多边形的线或与给定多边形的顶点之一相同,则应返回 true。为了处理这个问题,在检查从“p”到极端的线是否相交后,我们检查“p”是否与多边形当前线的顶点共线。如果共线,则检查点“p”是否位于多边形的当前侧,如果位于,则返回 true,否则返回 false。

以下是上述方法的实现: 

using System;
using System.Collections.Generic;

class Program
{
    // Define a structure to represent a point
    struct Point
    {
        public double x, y;
    }

    // Function to check if a point is inside a polygon
    static bool PointInPolygon(Point point, List<Point> polygon)
    {
        int numVertices = polygon.Count;
        double x = point.x, y = point.y;
        bool inside = false;

        // Store the first point in the polygon and initialize the second point
        Point p1 = polygon[0], p2;

        // Loop through each edge in the polygon
        for (int i = 1; i <= numVertices; i++)
        {
            // Get the next point in the polygon
            p2 = polygon[i % numVertices];

            // Check if the point is above the minimum y coordinate of the edge
            if (y > Math.Min(p1.y, p2.y))
            {
                // Check if the point is below the maximum y coordinate of the edge
                if (y <= Math.Max(p1.y, p2.y))
                {
                    // Check if the point is to the left of the maximum x coordinate of the edge
                    if (x <= Math.Max(p1.x, p2.x))
                    {
                        // Calculate the x-intersection of the line connecting the point to the edge
                        double xIntersection = (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;

                        // Check if the point is on the same line as the edge or to the left of the x-intersection
                        if (p1.x == p2.x || x <= xIntersection)
                        {
                            // Flip the inside flag
                            inside = !inside;
                        }
                    }
                }
            }

            // Store the current point as the first point for the next iteration
            p1 = p2;
        }

        // Return the value of the inside flag
        return inside;
    }

    // Driver code
    static void Main(string[] args)
    {
        // Define a point to test
        Point point = new Point { x = 150, y = 85 };

        // Define a polygon
        List<Point> polygon = new List<Point>
        {
            new Point { x = 186, y = 14 },
            new Point { x = 186, y = 44 },
            new Point { x = 175, y = 115 },
            new Point { x = 175, y = 85 }
        };

        // Check if the point is inside the polygon
        if (PointInPolygon(point, polygon))
        {
            Console.WriteLine("Point is inside the polygon");
        }
        else
        {
            Console.WriteLine("Point is outside the polygon");
        }
    }
}
 

输出:

Point is outside the polygon

时间复杂度: O(n),其中 n 是给定多边形的顶点数。

辅助空间: O(1),因为没有占用额外空间。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值