Пример #1
0
 /// <summary>
 /// 查找point是否在节点列表里面
 /// </summary>
 /// <param name="nodeList">节点列表</param>
 /// <param name="point">用于查找的节点</param>
 /// <param name="pIndex">返回节点索引</param>
 /// <returns>if inside,return sucess,else return not inside</returns>
 public static PolyResCode NavNodeGetNodeIndex(List <NavNode> nodeList, Vector2 point, out int pIndex)
 {
     pIndex = -1;
     for (int i = 0; i < nodeList.Count; i++)
     {
         NavNode node = nodeList[i];
         if (NMath.Equals(node.vertex, point))
         {
             pIndex = i;
             return(PolyResCode.Success);
         }
     }
     return(PolyResCode.ErrNotInside);
 }
Пример #2
0
        /// <summary>
        /// 合并两个节点列表,生成交点,并按顺时针序插入到顶点表中
        /// </summary>
        /// <param name="c0">主多边形顶点表,并返回插入交点后的顶点表</param>
        /// <param name="c1">合并多边形顶点表,并返回插入交点后的顶点表</param>
        /// <param name="nInsCnt">交点个数</param>
        /// <returns></returns>
        public static PolyResCode NavNodeIntersectPoint(List<NavNode> c0, List<NavNode> c1, out int nInsCnt)
        {
            nInsCnt = 0;

            NavNode startNode0 = c0[0];
            NavNode startNode1 = null;
            Line2D line0, line1;
            Vector2 insPoint;
            bool hasIns = false;

            while (startNode0 != null)
            {
                // 判断是否到末点了
                if (startNode0.next == null)
                    line0 = new Line2D(startNode0.vertex, c0[0].vertex);
                else
                    line0 = new Line2D(startNode0.vertex, startNode0.next.vertex);

                startNode1 = c1[0];
                hasIns = false;

                while (startNode1 != null)
                {
                    if (startNode1.next == null)
                        line1 = new Line2D(startNode1.vertex, c1[0].vertex);
                    else
                        line1 = new Line2D(startNode1.vertex, startNode1.next.vertex);

                    if (line0.Intersection(line1, out insPoint) == LineCrossState.CROSS)
                    {
                        int insPotIndex = -1;
                        //如果交点不在多边形的节点上
                        if (NavUtil.NavNodeGetNodeIndex(c0, insPoint, out insPotIndex) == PolyResCode.ErrNotInside)
                        {
                            nInsCnt++;
                            NavNode node0 = new NavNode(insPoint, true, true);
                            NavNode node1 = new NavNode(insPoint, true, false);

                            c0.Add(node0);
                            c1.Add(node1);

                            node0.other = node1;
                            node1.other = node0;

                            //插入顶点列表
                            node0.next = startNode0.next;
                            startNode0.next = node0;
                            node1.next = startNode1.next;
                            startNode1.next = node1;

                            if (line0.ClassifyPoint(line1.GetEndPoint()) == PointSide.RIGHT_SIDE)
                            {
                                node0.o = true;
                                node1.o = true;
                            }

                            hasIns = true;
                            break;
                        }
                    }
                    startNode1 = startNode1.next;

                }
                if (!hasIns)
                    startNode0 = startNode0.next;

            }

            return PolyResCode.Success;
        }
Пример #3
0
        // ========================================== 合并 ============================================= //

        /// <summary>
        /// 合并两个交叉的多边形(多边形必须先转换为顺时针方向,调用CW()函数!)
        /// </summary>
        /// <param name="other"></param>
        /// <param name="polyRes"></param>
        /// <returns></returns>
        public PolyResCode Union(Polygon other, ref List<Polygon> polyRes)
        {
            if (this.m_lstPoints.Count == 0 || other.m_lstPoints.Count == 0)
                return PolyResCode.ErrEmpty;
            else if (!NMath.CheckCross(GetCoverRect(), other.GetCoverRect()))
                return PolyResCode.ErrNotCross;

            // 转换为顺时针方向
            //this.CW();
            //other.CW();

            List<NavNode> mainNode = new List<NavNode>();     //主多边形顶点
            List<NavNode> subNode = new List<NavNode>();      //需要合并的多边形顶点

            // init main nodes
            for (int i = 0; i < this.m_lstPoints.Count; i++)
            {
                NavNode currNode = new NavNode(this.m_lstPoints[i], false, true);
                if (i > 0)
                {
                    NavNode preNode = mainNode[i - 1];
                    preNode.next = currNode;
                }
                mainNode.Add(currNode);
            }

            // init sub nodes
            for (int j = 0; j < other.m_lstPoints.Count; j++)
            {
                NavNode currNode = new NavNode(other.m_lstPoints[j], false, false);
                if (j > 0)
                {
                    NavNode preNode = subNode[j - 1];
                    preNode.next = currNode;
                }
                subNode.Add(currNode);
            }

            int insCnt = 0;
            PolyResCode result = NavUtil.NavNodeIntersectPoint(mainNode, subNode, out insCnt);
            if (result == PolyResCode.Success && insCnt > 0)
            {
                if (insCnt % 2 != 0)
                {
                    return PolyResCode.ErrCrossNum;
                }
                else
                {
                    PolyResCode linkRes = NavUtil.LinkToPolygon(mainNode, subNode, ref polyRes);
                    return linkRes;
                }
            }

            return PolyResCode.ErrCrossNum;
        }
Пример #4
0
        /// <summary>
        /// 合并两个节点列表,生成交点,并按顺时针序插入到顶点表中
        /// </summary>
        /// <param name="c0">主多边形顶点表,并返回插入交点后的顶点表</param>
        /// <param name="c1">合并多边形顶点表,并返回插入交点后的顶点表</param>
        /// <param name="nInsCnt">交点个数</param>
        /// <returns></returns>
        public static PolyResCode NavNodeIntersectPoint(List <NavNode> c0, List <NavNode> c1, out int nInsCnt)
        {
            nInsCnt = 0;

            NavNode startNode0 = c0[0];
            NavNode startNode1 = null;
            Line2D  line0, line1;
            Vector2 insPoint;
            bool    hasIns = false;

            while (startNode0 != null)
            {
                // 判断是否到末点了
                if (startNode0.next == null)
                {
                    line0 = new Line2D(startNode0.vertex, c0[0].vertex);
                }
                else
                {
                    line0 = new Line2D(startNode0.vertex, startNode0.next.vertex);
                }

                startNode1 = c1[0];
                hasIns     = false;

                while (startNode1 != null)
                {
                    if (startNode1.next == null)
                    {
                        line1 = new Line2D(startNode1.vertex, c1[0].vertex);
                    }
                    else
                    {
                        line1 = new Line2D(startNode1.vertex, startNode1.next.vertex);
                    }

                    if (line0.Intersection(line1, out insPoint) == LineCrossState.CROSS)
                    {
                        int insPotIndex = -1;
                        //如果交点不在多边形的节点上
                        if (NavUtil.NavNodeGetNodeIndex(c0, insPoint, out insPotIndex) == PolyResCode.ErrNotInside)
                        {
                            nInsCnt++;
                            NavNode node0 = new NavNode(insPoint, true, true);
                            NavNode node1 = new NavNode(insPoint, true, false);

                            c0.Add(node0);
                            c1.Add(node1);

                            node0.other = node1;
                            node1.other = node0;

                            //插入顶点列表
                            node0.next      = startNode0.next;
                            startNode0.next = node0;
                            node1.next      = startNode1.next;
                            startNode1.next = node1;

                            if (line0.ClassifyPoint(line1.GetEndPoint()) == PointSide.RIGHT_SIDE)
                            {
                                node0.o = true;
                                node1.o = true;
                            }

                            hasIns = true;
                            break;
                        }
                    }
                    startNode1 = startNode1.next;
                }
                if (!hasIns)
                {
                    startNode0 = startNode0.next;
                }
            }

            return(PolyResCode.Success);
        }
Пример #5
0
        /// <summary>
        /// 合并两个节点列表为一个多边形,结果为顺时针序( 生成的内部孔洞多边形为逆时针序)
        /// </summary>
        /// <param name="mainNode"></param>
        /// <param name="subNode"></param>
        /// <param name="polyRes"></param>
        /// <returns></returns>
        public static PolyResCode LinkToPolygon(List <NavNode> mainNode, List <NavNode> subNode, ref List <Polygon> polyRes)
        {
            polyRes.Clear();
            for (int i = 0; i < mainNode.Count; i++)
            {
                NavNode currNode = mainNode[i];

                // 选择一个没有访问过的交点做起始点
                if (currNode.isIns && !currNode.passed)
                {
                    List <Vector2> points = new List <Vector2>();
                    while (currNode != null)
                    {
                        currNode.passed = true;

                        //交点转换
                        if (currNode.isIns)
                        {
                            currNode.other.passed = true;

                            if (!currNode.o)                   //该交点为进点(跟踪裁剪多边形边界)
                            {
                                if (currNode.isMain)           //当前点在主多边形中
                                {
                                    currNode = currNode.other; //切换到裁剪多边形中
                                }
                            }
                            else
                            {
                                //该交点为出点(跟踪主多边形边界)
                                if (!currNode.isMain)          //当前点在裁剪多边形中
                                {
                                    currNode = currNode.other; //切换到主多边形中
                                }
                            }
                        }

                        points.Add(currNode.vertex);

                        if (currNode.next == null)
                        {
                            if (currNode.isMain)
                            {
                                currNode = mainNode[0];
                            }
                            else
                            {
                                currNode = subNode[0];
                            }
                        }
                        else
                        {
                            currNode = currNode.next;
                        }

                        if (currNode.vertex == points[0])
                        {
                            break;
                        }
                    }

                    // 删除重复顶点
                    Polygon poly = new Polygon(points);
                    poly.DelRepeatPoint();
                    polyRes.Add(poly);
                }
            }
            return(PolyResCode.Success);
        }