判断点是否在多边形内部或者在边上(C#)

namespace GeometricAlgorithm
{
class XYZ
{
private double x;
private double y;
private double z;
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return y; }
set { y = value; }
}
public double Z
{
get { return z; }
set { z = value; }
}
public XYZ(double x,double y,double z)
{
X = x;Y = y;Z = z;
}
}

class PointIn
{   
    //只在内部不在边上
    //水平/垂直交叉点数判别法(适用于任意多边形)
    //注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1, P2),
    //1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况
    //2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。
    //3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。
    //4)再判断相交之前,先判断P是否在边(P1, P2)的上面,如果在,则直接得出结论:P再多边形内部。
    //再经典不过的算法了:
    // 功能:判断点是否在多边形内
    // 方法:求解通过该点的水平线与多边形各边的交点
    // 结论:单边交点为奇数,成立! 



    public bool PtInPolygon(XYZ p,List ptPolygon, int nCount)
    {
        int nCross = 0;

        for (int i = 0; i < nCount; i++)
        {
            XYZ p1 = ptPolygon[i];
            XYZ p2 = ptPolygon[i+1];

            // 求解 y=p.y 与 p1p2 的交点

            if (p1.Y == p2.Y) // p1p2 与 y=p0.y平行
                continue;

            if ((p.Y < p1.Y) && (p.Y < p2.Y)) // 交点在p1p2延长线上
                continue;
            if ((p.Y >= p1.Y) && (p.Y >= p2.Y)) // 交点在p1p2延长线上
                continue;

            // 求交点的 X 坐标 --------------------------------------------------------------
            double x = (p.Y  - p1.Y) * (p2.X - p1.X ) / (p2.Y- p1.Y) + p1.X;

            if (x > p.X)
                nCross++; // 只统计单边交点
        }
       
        // 单边交点为偶数,点在多边形之外 ---
        return (nCross % 2 == 1);
    }


    //1)首先判断Q是否在直线P1P2上。
    //判断方法:用叉乘,QP1 × P1P2 = 0,即(Q - P1) *(P1 - P2) = 0;
    //2)考虑Q是否在P1P2的反向延迟线上,即Q在以P1、P2为对角顶点的矩形内。
    //判断方法:设Q(a, b),P1(x1, y1),P2(x2,y2)且x1 ptPolygon, int nCount)
    {
        bool a=false;
        bool b=false;
       
        for (int i=0;ib)
        {
            return a;
        }
        else
        {
            return b;
        }
    }
    public double Min(double a, double b)
    {
        if (a < b)
        {
            return a;
        }
        else
        {
            return b;
        }
    }
}

}

static void Main(string[] args)
{
bool a = false;
List ptPolygon = new List()
{ new XYZ(1, 1, 0), new XYZ(1, -1, 0) , new XYZ(-1, -1, 0) ,
new XYZ(-1, 1, 0) ,new XYZ(1, 1, 0)};
PointIn px = new PointIn();
if (px.PtInPolygon(new XYZ(0.9, 0.9, 0), ptPolygon, 4)|| px.OnLine(new XYZ(0.9, 0.9, 0), ptPolygon, 4))
{
a = true;
}
else
{
a = false;
}
Console.WriteLine(a);
Console.ReadKey();
}

你可能感兴趣的:(几何计算)