Пример #1
0
        /////////////////////////////////////////////////////////////////////////////////////////////////////////
        #region LOS视线检测相关

        //---------------------------------------------------------------------------------------------------------
        //松弛疗法,微调pos,直到该点真正地处于某个多边形中为止
        //【遗留问题】没有考虑松弛过程中发生进入不可进入区域的情况
        Belong_Status RelaxPostion(ref Vector2 pos, out Polygon poly)
        {
            Vector2 p = pos;

            Object        obj = null;
            Belong_Status ret = GetPointLocation(p, out obj);             //第一次

            if (ret == Belong_Status.Invalid)
            {
                poly = null;
                return(ret);                        //不用松弛了,直接返回
            }

            Random rand = new Random((int)DateTime.Now.Ticks);
            bool   ok   = (ret == Belong_Status.Polygon);

            while (!ok)
            {
                p.X = pos.X + (float)(rand.NextDouble() - 0.5d) / 10f;
                p.Y = pos.Y + (float)(rand.NextDouble() - 0.5d) / 10f;
                ret = GetPointLocation(p, out obj);
                ok  = (ret == Belong_Status.Polygon);
            }

            pos  = p;
            poly = (Polygon)obj;
            return(ret);
        }
Пример #2
0
        //点与单个多边形的关系检测
        //- 如果点在多边形内部,retobj返回该多边形
        //- 如果点在多边形的边上,retobj返回该边
        //- 如果点在多边形的顶点上,retobj返回该点
        //- 如果点在多边形之外,retobj返回null
        public Belong_Status PointPolygonRelationshipTest(Vector2 pos, Polygon poly, out Object retobj)
        {
            //默认情况:点处于多边形以内
            retobj = poly;
            Belong_Status result = Belong_Status.Polygon;

            foreach (Edge e in poly.edges)
            {
                Vector2 between = new Vector2(e.to.x - e.from.x, e.to.y - e.from.y);
                Vector2 from    = new Vector2(pos.X - e.from.x, pos.Y - e.from.y);

                float test = Vector2.Ccw(between, from);

                if (FloatEqual(test, 0))                                                                //在边上或在顶点上
                {
                    Vector2 to = new Vector2(pos.X - e.to.x, pos.Y - e.to.y);

                    if (FloatEqual(from.LengthSq(), 0))                                         //在顶点e.from上
                    {
                        retobj = e.from;
                        result = Belong_Status.Vertex;
                    }
                    else if (FloatEqual(to.LengthSq(), 0))                              //在顶点e.to上
                    {
                        retobj = e.to;
                        result = Belong_Status.Vertex;
                    }
                    else                                                                                                //在边上
                    {
                        retobj = e;
                        result = Belong_Status.Edge;
                    }
                    break;
                }
                if (test < 0)                                                                                   //点处于polygon之外
                {
                    retobj = null;
                    result = Belong_Status.OutOfPolygon;
                    break;
                }
            }
            return(result);
        }
Пример #3
0
        /////////////////////////////////////////////////////////////////////////////////////////////////////////
        #region 快速检测点处于哪个多边形中

        //快速检测点的位置
        //- retobj: 要么返回一个多边形,要么返回一条边,要么返回一个点
        //- 返回值: true,成功检测出了点的位置;false,点处于不合法位置
        public Belong_Status GetPointLocation(Vector2 p, out Object retobj)
        {
            retobj = null;
            Belong_Status ret = Belong_Status.Invalid;

            for (int i = 0; i < polys.Length; i++)
            {
                Polygon poly = polys[i];
                if ((p.X >= poly.min.X && p.X <= poly.max.X) &&
                    (p.Y >= poly.min.Y && p.Y <= poly.max.Y))
                {
                    Object        obj;
                    Belong_Status result = PointPolygonRelationshipTest(p, poly, out obj);

                    if (result == Belong_Status.Polygon)
                    {
                        ret = result; retobj = obj;
                        Debug.WriteLine(string.Format("(点位置检测) P:{0}", poly.idx));
                        break;
                    }
                    else if (result == Belong_Status.Edge)
                    {
                        ret = result; retobj = obj;

                        Edge e = (Edge)obj;
                        Debug.WriteLine(string.Format("(点位置检测) P:{0} E:({1}-{2})", poly.idx, e.belong_poly, e.neighbor_poly));
                        break;
                    }
                    else if (result == Belong_Status.Vertex)
                    {
                        ret = result; retobj = obj;

                        FPoint pos = (FPoint)obj;
                        Debug.WriteLine(string.Format("(点位置检测) P:{0} V:({1},{2})", poly.idx, pos.x, pos.y));
                        break;
                    }
                }
            }
            return(ret);
        }