コード例 #1
0
        private void AddCurPosToNaviMap(GraphPoint <NaviPoint>[] map, GraphPoint <NaviPoint> curNaviP,
                                        int prePointSum, List <Segment> guardLines, List <Segment> borderLines)
        {
            map[prePointSum] = curNaviP;
            for (int i = 0; i < prePointSum; i++)
            {
                Segment seg = new Segment(curNaviP.value.Pos, map[i].value.Pos);

                bool cross = false;
                foreach (Segment guardLine in guardLines)
                {
                    if (Segment.IsCross(guardLine, seg))
                    {
                        cross = true;
                        break;
                    }
                }

                if (!cross)
                {
                    foreach (Segment borderLine in borderLines)
                    {
                        if (Segment.IsCross(borderLine, seg))
                        {
                            cross = true;
                            break;
                        }
                    }
                }

                if (!cross)
                {
                    float weight = Vector2.Distance(curNaviP.value.Pos, map[i].value.Pos);
                    GraphPoint <NaviPoint> .Link(map[i], curNaviP, weight);
                }
            }
        }
コード例 #2
0
        private void AddAimPosToNaviMap(GraphPoint <NaviPoint>[] map, GraphPoint <NaviPoint> aimNaviP, GraphPoint <NaviPoint> curNaviP,
                                        int prePointSum, List <Segment> guardLines, List <Segment> borderLines)
        {
            map[prePointSum + 1] = aimNaviP;
            for (int i = 0; i < prePointSum; i++)
            {
                Segment seg = new Segment(aimNaviP.value.Pos, map[i].value.Pos);

                bool cross = false;
                foreach (Segment guardLine in guardLines)
                {
                    if (Segment.IsCross(guardLine, seg))
                    {
                        cross = true;
                        break;
                    }
                }

                if (!cross)
                {
                    foreach (Segment borderLine in borderLines)
                    {
                        if (Segment.IsCross(borderLine, seg))
                        {
                            cross = true;
                            break;
                        }
                    }
                }

                if (!cross)
                {
                    float weight = Vector2.Distance(aimNaviP.value.Pos, map[i].value.Pos);
                    GraphPoint <NaviPoint> .Link(map[i], aimNaviP, weight);
                }
            }

            Segment curToAim = new Segment(curNaviP.value.Pos, aimNaviP.value.Pos);

            bool link = true;

            foreach (Segment guardLine in guardLines)
            {
                if (Segment.IsCross(guardLine, curToAim))
                {
                    if (MathTools.Vector2Cross(guardLine.endPoint - guardLine.startPoint, curNaviP.value.Pos - guardLine.endPoint) < 0)
                    {
                        link = false;
                        break;
                    }
                }
            }

            if (link)
            {
                foreach (Segment borderLine in borderLines)
                {
                    if (Segment.IsCross(borderLine, curToAim))
                    {
                        link = false;
                        break;
                    }
                }
            }

            if (link)
            {
                float weight = Vector2.Distance(curNaviP.value.Pos, aimNaviP.value.Pos);
                GraphPoint <NaviPoint> .Link(curNaviP, aimNaviP, weight);
            }
        }
コード例 #3
0
        public void BuildMap(EyeableBorderObjInfo[] objInfos, Rectanglef mapBorder, float spaceForTank)
        {
            #region 对每一个BorderObj生成逻辑坐标上的凸包点集,并向外扩展

            borderLines = new List <Segment>();

            convexs = new List <GuardConvex>();
            foreach (EyeableBorderObjInfo obj in objInfos)
            {
                if (obj.ConvexHall == null || obj.IsDisappeared || obj.ConvexHall.Points == null)
                {
                    continue;
                }

                Matrix matrix = obj.EyeableInfo.CurTransMatrix;

                GraphPoint <NaviPoint>[] convexHall;

                List <BordPoint> bordPoints = obj.ConvexHall.Points;
                if (bordPoints.Count > 2)
                {
                    List <GraphPoint <NaviPoint> > list = new List <GraphPoint <NaviPoint> >();
                    for (int i = 0; i < bordPoints.Count; i++)
                    {
                        Vector2 lastPos = Vector2.Transform(ConvertHelper.PointToVector2(bordPoints[i - 1 < 0 ? bordPoints.Count - 1 : i - 1].p), matrix);
                        Vector2 curPos  = Vector2.Transform(ConvertHelper.PointToVector2(bordPoints[i].p), matrix);
                        Vector2 nextPos = Vector2.Transform(ConvertHelper.PointToVector2(bordPoints[(i + 1) % bordPoints.Count].p), matrix);

                        Vector2 v1  = curPos - lastPos;
                        Vector2 v2  = curPos - nextPos;
                        float   ang = MathTools.AngBetweenVectors(v1, v2);
                        if (ang >= MathHelper.PiOver2)
                        {
                            float   halfDes = (float)(spaceForTank / Math.Sin(ang));
                            Vector2 delta   = halfDes * Vector2.Normalize(v1) + halfDes * Vector2.Normalize(v2);
                            list.Add(new GraphPoint <NaviPoint>(
                                         new NaviPoint(obj, bordPoints[i].index, curPos + delta), new List <GraphPath <NaviPoint> >()));
                        }
                        else
                        {
                            v1.Normalize();
                            v2.Normalize();
                            Vector2 cenV   = Vector2.Normalize(v1 + v2);
                            Vector2 vertiV = new Vector2(cenV.Y, -cenV.X);
                            float   ang2   = MathHelper.PiOver4 - 0.25f * ang;
                            float   vertiL = (float)(spaceForTank * Math.Tan(ang2));

                            list.Add(new GraphPoint <NaviPoint>(
                                         new NaviPoint(obj, bordPoints[i].index, curPos + spaceForTank * cenV + vertiL * vertiV),
                                         new List <GraphPath <NaviPoint> >()));
                            list.Add(new GraphPoint <NaviPoint>(
                                         new NaviPoint(obj, bordPoints[i].index, curPos + spaceForTank * cenV - vertiL * vertiV),
                                         new List <GraphPath <NaviPoint> >()));
                        }

                        // 添加borderLine
                        borderLines.Add(new Segment(curPos, nextPos));
                    }
                    convexHall = list.ToArray();
                    convexs.Add(new GuardConvex(convexHall));
                }
                else if (bordPoints.Count == 2)
                {
                    convexHall = new GraphPoint <NaviPoint> [4];
                    Vector2 startPos = Vector2.Transform(ConvertHelper.PointToVector2(bordPoints[0].p), matrix);
                    Vector2 endPos   = Vector2.Transform(ConvertHelper.PointToVector2(bordPoints[1].p), matrix);
                    Vector2 dir      = endPos - startPos;
                    dir.Normalize();
                    Vector2 normal = new Vector2(dir.Y, -dir.X);
                    convexHall[0] = new GraphPoint <NaviPoint>(
                        new NaviPoint(obj, bordPoints[0].index, startPos - dir * spaceForTank), new List <GraphPath <NaviPoint> >());
                    convexHall[1] = new GraphPoint <NaviPoint>(
                        new NaviPoint(obj, bordPoints[0].index, startPos + spaceForTank * normal), new List <GraphPath <NaviPoint> >());
                    convexHall[2] = new GraphPoint <NaviPoint>(
                        new NaviPoint(obj, bordPoints[1].index, endPos + spaceForTank * normal), new List <GraphPath <NaviPoint> >());
                    convexHall[3] = new GraphPoint <NaviPoint>(
                        new NaviPoint(obj, bordPoints[1].index, endPos + dir * spaceForTank), new List <GraphPath <NaviPoint> >());

                    //if (float.IsNaN( convexHall[0].value.Pos.X ) || float.IsNaN( convexHall[1].value.Pos.X ))
                    //{

                    //}

                    // 添加borderLine
                    borderLines.Add(new Segment(startPos, endPos));

                    convexs.Add(new GuardConvex(convexHall));
                }
            }

            #endregion

            #region 得到警戒线

            guardLines = new List <Segment>();

            foreach (GuardConvex convex in convexs)
            {
                for (int i = 0; i < convex.points.Length; i++)
                {
                    guardLines.Add(new Segment(convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos));

                    //if (float.IsNaN( convex[i].value.Pos.X ))
                    //{

                    //}
                }
            }

            mapBorder = new Rectanglef(mapBorder.X + spaceForTank, mapBorder.Y + spaceForTank,
                                       mapBorder.Width - 2 * spaceForTank, mapBorder.Height - 2 * spaceForTank);

            guardLines.Add(new Segment(mapBorder.UpLeft, mapBorder.UpRight));
            guardLines.Add(new Segment(mapBorder.UpRight, mapBorder.DownRight));
            guardLines.Add(new Segment(mapBorder.DownRight, mapBorder.DownLeft));
            guardLines.Add(new Segment(mapBorder.DownLeft, mapBorder.UpLeft));

            #endregion

            #region 检查凸包内部连线是否和警戒线相交,如不相交则连接该连线并计算权值

            foreach (GuardConvex convex in convexs)
            {
                for (int i = 0; i < convex.Length; i++)
                {
                    // 检查连线是否超出边界
                    if (!mapBorder.Contains(convex[i].value.Pos))
                    {
                        continue;
                    }

                    Segment link = new Segment(convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos);


                    bool isCross = false;
                    foreach (Segment guardLine in guardLines)
                    {
                        if (link.Equals(guardLine))
                        {
                            continue;
                        }

                        if (Segment.IsCross(link, guardLine))
                        {
                            isCross = true;
                            break;
                        }
                    }

                    if (!isCross)
                    {
                        float weight = Vector2.Distance(convex[i].value.Pos, convex[(i + 1) % convex.Length].value.Pos);
                        //if (float.IsNaN( weight ))
                        //{

                        //}
                        GraphPoint <NaviPoint> .Link(convex[i], convex[(i + 1) % convex.Length], weight);
                    }
                }
            }

            #endregion

            #region 检查凸包之间连线是否与警戒线以及边界线相交,如不相交则连接并计算权值

            for (int i = 0; i < convexs.Count - 1; i++)
            {
                for (int j = i + 1; j < convexs.Count; j++)
                {
                    foreach (GraphPoint <NaviPoint> p1 in convexs[i].points)
                    {
                        // 检查连线是否超出边界
                        if (!mapBorder.Contains(p1.value.Pos))
                        {
                            continue;
                        }

                        foreach (GraphPoint <NaviPoint> p2 in convexs[j].points)
                        {
                            Segment link = new Segment(p1.value.Pos, p2.value.Pos);

                            bool isCross = false;
                            foreach (Segment guardLine in guardLines)
                            {
                                if (Segment.IsCross(link, guardLine))
                                {
                                    isCross = true;
                                    break;
                                }
                            }
                            if (!isCross)
                            {
                                foreach (Segment borderLine in borderLines)
                                {
                                    if (Segment.IsCross(link, borderLine))
                                    {
                                        isCross = true;
                                        break;
                                    }
                                }
                            }

                            if (!isCross)
                            {
                                float weight = Vector2.Distance(p1.value.Pos, p2.value.Pos);
                                //if (float.IsNaN( weight ))
                                //{

                                //}
                                GraphPoint <NaviPoint> .Link(p1, p2, weight);
                            }
                        }
                    }
                }
            }

            #endregion

            #region 整理导航图

            List <GraphPoint <NaviPoint> > points = new List <GraphPoint <NaviPoint> >();

            foreach (GuardConvex convex in convexs)
            {
                foreach (GraphPoint <NaviPoint> p in convex.points)
                {
                    points.Add(p);
                }
            }

            naviGraph = points.ToArray();

            #endregion
        }