求...判断一个点是不是在(不规则)四边形当中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求...判断一个点是不是在(不规则)四边形当中相关的知识,希望对你有一定的参考价值。

首先给出四个点的坐标,然后在cin目标点的坐标.
判断这个点是否在此四边形当中. 仁兄注意,是任意四边形!
会发生的情况很多,请君留心......
最好给个公式之类的. 用Ctrl+c Ctrl +v 的 闪远点!
高手来..........
最好有c++ 代码 。
现在网上的都十分不精确!
求高手帮忙, 弟弟万分感谢。。。。 555

1、若有3点共线 4个点不构成4边形
2、无三点共线 三点构成三角形 另外一点在三角形内
则4个点可以构成3个 凹四边形 没有任何一点同时属于这3个凹四边形(这里把在边上的点认为不在四边形内)在三角形内的点都有可能属于某个四边形
3、四点构成凸四边形 设4点位A,B,C,D
求出直线AB和CD AC和BD AD 和BC得交点 若交点在线段AB 或AC或AD上则舍去这组 剩余两组 则为四边形4边 比如四边为 AB 和CD, AD和BC 则把点P坐标带入AB,CD方程 若二者异号 则说明点在2直线之间 同理验证AD和BC 都异号的话说明P在四边形内部
参考技术A 从点所在位置做一个水平或者垂直的射线
计算它和多边形的交点,奇数在内,偶数在外

所以要先编一个被调程序实现求四边形四边的方程(线段,规定x的范围);然后求射线方程(若作水平射线则限定x范围,垂直则限定y的范围)与四边的交点数;再求射线与四边的交战。再判断奇偶性即可。

建议你看看凸包算法,也可以用这个来判断。
参考技术B 依题意应该是平面四点
平面四点组成的任意四边形,就是四点的连线组成的四边形
仅且仅有这一种情况
再判断目标点是否再四边形内,都很容易了本回答被提问者采纳
参考技术C 从点所在位置做一个水平或者垂直的射线计算它和多边形的交点,奇数在内,偶数在外

可以尽管放心用,这是一个计算机图形学的基本算法思想。
参考技术D 由四个点判断任意四边形的四条边所在直线
然后以(0,0)为标准判断目标点(a,b)与四条直线的位置关系
综合四个关系判断目标点是否在这四条直线所围成的四边形里

点在多边形内算法,C#判断一个点是否在一个复杂多边形的内部

判断一点是否在不规则图像的内部算法,如下图是由一个个点组成的不规则图像,判断某一点是否在不规则矩形内部,先上效果图

技术分享

算法实现如下,算法简单,亲试有效

 

    public class PositionAlgorithmHelper
    {
        /// <summary>
        /// 判断当前位置是否在不规则形状里面
        /// </summary>
        /// <param name="nvert">不规则形状的定点数</param>
        /// <param name="vertx">当前x坐标</param>
        /// <param name="verty">当前y坐标</param>
        /// <param name="testx">不规则形状x坐标集合</param>
        /// <param name="testy">不规则形状y坐标集合</param>
        /// <returns></returns>
        public static bool PositionPnpoly(int nvert, List<double> vertx, List<double> verty, double testx, double testy)
        {
            int i, j, c = 0;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                if (((verty[i] > testy) != (verty[j] > testy)) && (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
                {
                    c = 1 + c; ;
                }
            }
            if (c % 2 == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

用上图坐标进行测试:

    class Program
    {
        static void Main(string[] args)
        {
            test1();
        }

        /// <summary>
        /// test1
        /// </summary>
        public static void test1()
        {
            //不规则图像坐标
            List<Position> position = new List<Position>();
            position.Add(new Position() { x = 6, y = 0 });
            position.Add(new Position() { x = 10, y = 2 });
            position.Add(new Position() { x = 16, y = 2 });
            position.Add(new Position() { x = 20, y = 6 });
            position.Add(new Position() { x = 14, y = 10 });
            position.Add(new Position() { x = 16, y = 6 });
            position.Add(new Position() { x = 12, y = 6 });
            position.Add(new Position() { x = 14, y = 8 });
            position.Add(new Position() { x = 10, y = 8 });
            position.Add(new Position() { x = 8, y = 6 });
            position.Add(new Position() { x = 12, y = 4 });
            position.Add(new Position() { x = 6, y = 4 });
            position.Add(new Position() { x = 8, y = 2 });

            //用户当前位置坐标
            List<Position> userPositions = new List<Position>();
            userPositions.Add(new Position() { x = 14, y = 4 });
            userPositions.Add(new Position() { x = 15, y = 4 });
            userPositions.Add(new Position() { x = 10, y = 6 });
            userPositions.Add(new Position() { x = 8, y = 5 });

            //不规则图像x坐标集合
            List<double> xList = position.Select(x => x.x).ToList();
            //不规则图像y坐标集合
            List<double> yList = position.Select(x => x.y).ToList();

            foreach (var userPosition in userPositions)
            {
                bool result = PositionAlgorithmHelper.PositionPnpoly(position.Count, xList, yList, userPosition.x, userPosition.y);

                if (result)
                {
                    Console.WriteLine(string.Format("{0},{1}【在】坐标内", userPosition.x, userPosition.y));
                }
                else
                {
                    Console.WriteLine(string.Format("{0},{1}【不在】坐标内", userPosition.x, userPosition.y));
                }
            }
        }
    }

另外两种方式:

        /// <summary>  
        /// 判断点是否在多边形内.  
        /// ----------原理----------  
        /// 注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,  
        /// 如果P在多边形外部,则交点个数必为偶数(0也在内)。  
        /// 所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1,P2),  
        /// 1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况  
        /// 2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。  
        /// 3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。  
        /// 4)再判断相交之前,先判断P是否在边(P1,P2)的上面,如果在,则直接得出结论:P再多边形内部。  
        /// </summary>  
        /// <param name="checkPoint">要判断的点</param>  
        /// <param name="polygonPoints">多边形的顶点</param>  
        /// <returns></returns>  
        public static bool IsInPolygon2(Position checkPoint, List<Position> polygonPoints)
        {
            int counter = 0;
            int i;
            double xinters;
            Position p1, p2;
            int pointCount = polygonPoints.Count;
            p1 = polygonPoints[0];
            for (i = 1; i <= pointCount; i++)
            {
                p2 = polygonPoints[i % pointCount];
                if (checkPoint.y > Math.Min(p1.y, p2.y)//校验点的Y大于线段端点的最小Y  
                    && checkPoint.y <= Math.Max(p1.y, p2.y))//校验点的Y小于线段端点的最大Y  
                {
                    if (checkPoint.x <= Math.Max(p1.x, p2.x))//校验点的X小于等线段端点的最大X(使用校验点的左射线判断).  
                    {
                        if (p1.y != p2.y)//线段不平行于X轴  
                        {
                            xinters = (checkPoint.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
                            if (p1.x == p2.x || checkPoint.x <= xinters)
                            {
                                counter++;
                            }
                        }
                    }

                }
                p1 = p2;
            }

            if (counter % 2 == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>  
        /// 判断点是否在多边形内.  
        /// ----------原理----------  
        /// 注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,  
        /// 如果P在多边形外部,则交点个数必为偶数(0也在内)。  
        /// </summary>  
        /// <param name="checkPoint">要判断的点</param>  
        /// <param name="polygonPoints">多边形的顶点</param>  
        /// <returns></returns>  
        public static bool IsInPolygon(Position checkPoint, List<Position> polygonPoints)
        {
            bool inside = false;
            int pointCount = polygonPoints.Count;
            Position p1, p2;
            for (int i = 0, j = pointCount - 1; i < pointCount; j = i, i++)//第一个点和最后一个点作为第一条线,之后是第一个点和第二个点作为第二条线,之后是第二个点与第三个点,第三个点与第四个点...  
            {
                p1 = polygonPoints[i];
                p2 = polygonPoints[j];
                if (checkPoint.y < p2.y)
                {//p2在射线之上  
                    if (p1.y <= checkPoint.y)
                    {//p1正好在射线中或者射线下方  
                        if ((checkPoint.y - p1.y) * (p2.x - p1.x) > (checkPoint.x - p1.x) * (p2.y - p1.y))//斜率判断,在P1和P2之间且在P1P2右侧  
                        {
                            //射线与多边形交点为奇数时则在多边形之内,若为偶数个交点时则在多边形之外。  
                            //由于inside初始值为false,即交点数为零。所以当有第一个交点时,则必为奇数,则在内部,此时为inside=(!inside)  
                            //所以当有第二个交点时,则必为偶数,则在外部,此时为inside=(!inside)  
                            inside = (!inside);
                        }
                    }
                }
                else if (checkPoint.y < p1.y)
                {
                    //p2正好在射线中或者在射线下方,p1在射线上  
                    if ((checkPoint.y - p1.y) * (p2.x - p1.x) < (checkPoint.x - p1.x) * (p2.y - p1.y))//斜率判断,在P1和P2之间且在P1P2右侧  
                    {
                        inside = (!inside);
                    }
                }
            }
            return inside;
        }  

 

以上是关于求...判断一个点是不是在(不规则)四边形当中的主要内容,如果未能解决你的问题,请参考以下文章

点在多边形内算法,C#判断一个点是否在一个复杂多边形的内部

怎么判断某一点在一个不规则的图形内部

跪求!!用C#在ArcEngine环境下开发一个求“图形(包括各种不规则多边形)”最小外接圆面积的方法函数

CAD里面怎么画不规则四边形的外接矩形?

判断点是否在任意多边形内

CAD怎么画不规则多边形