Example #1
0
        public void TraversePositionSet_ConnectedAndSpringEvent(IPositionSet ps)
        {
            if (OnGetConnection != null)
            {
                IPosition_Connected[] ary = (IPosition_Connected[])ps.ToArray();
                if (ary != null)
                {
                    foreach (IPosition_Connected p in ary)
                    {
                        float x = layer.ConvertPositionSetXToScreenX(p.GetX());
                        float y = layer.ConvertPositionSetYToScreenY(p.GetY());
                        IPositionSet_Connected_Adjacency adj_set = p.GetAdjacencyPositionSet();
                        adj_set.InitToTraverseSet();
                        while (adj_set.NextPosition())
                        {
                            IPosition_Connected adj = adj_set.GetPosition_Connected();
                            float adj_x             = layer.ConvertPositionSetXToScreenX(adj.GetX());
                            float adj_y             = layer.ConvertPositionSetYToScreenY(adj.GetY());
                            OnGetConnection(x, y, adj_x, adj_y);
                        }
                    }
                }
            }

            TraversePositionSetAndSpringEvent(ps);
        }
Example #2
0
        //没有路径则返回null
        public List <IPosition_Connected> SearchPath(IPosition_Connected start, IPosition_Connected end)
        {
            IPart_Connected startParentPart = ((Tag_M2M_Position)(start.GetAttachment())).parentPart;
            IPart_Connected endParentPart   = ((Tag_M2M_Position)(end.GetAttachment())).parentPart;

            ushort lastLevelTimeStamp = TimeStamp.getRandomTimeStamp();
            ushort endTime_stamp      = TimeStamp.getRandomTimeStamp();
            ushort startTime_stamp    = TimeStamp.getRandomTimeStamp();

            //从最上层的下一层开始进行搜索空间收缩
            for (int levelSequence = 1; levelSequence < m2mStructure.GetLevelNum(); levelSequence++)
            {
                IPart_Connected currentLevelAncestorPartOfStartPosition = startParentPart;
                IPart_Connected currentLevelAncestorPartOfEndPosition   = endParentPart;

                for (int i = 0; i < m2mStructure.GetLevelNum() - levelSequence - 1; i++)
                {
                    currentLevelAncestorPartOfStartPosition = (IPart_Connected)currentLevelAncestorPartOfStartPosition.GetParentPart();
                    currentLevelAncestorPartOfEndPosition   = (IPart_Connected)currentLevelAncestorPartOfEndPosition.GetParentPart();
                }

                Tag_M2M_Part StartPartTag = (Tag_M2M_Part)currentLevelAncestorPartOfStartPosition.GetAttachment();
                StartPartTag.isNeedToSearch = true;

                Tag_M2M_Part EndPartTag = (Tag_M2M_Part)currentLevelAncestorPartOfEndPosition.GetAttachment();
                EndPartTag.isNeedToSearch = true;

                bool isTopLevel = false;
                if (levelSequence == 1)
                {
                    isTopLevel = true;
                }

                //在该层中标记需要搜索的分块
                {
                    //归入搜索空间的路径的最长长度
                    float PathLengthBound = float.MaxValue;

                    endTime_stamp = TimeStamp.getNextTimeStamp(startTime_stamp);

                    EndPartTag.timeStamp = endTime_stamp;
                    EndPartTag.ge        = 0;

                    open.clear();
                    ((M2M_Part_TagComparer)com).state = 0;

                    //将起点加入open表
                    open.add(currentLevelAncestorPartOfEndPosition);

                    //当open表非空时
                    while (open.getSize() > 0)
                    {
                        //获得下一个最近的点
                        IPart_Connected currentPosition_Connected  = (IPart_Connected)open.removeFirst();
                        Tag_M2M_Part    TagOfCurrentPart_Connected = (Tag_M2M_Part)currentPosition_Connected.GetAttachment();

                        //当open表里面所有的点的g值都超出路径最大长度范围,则结束循环
                        if (TagOfCurrentPart_Connected.ge >= PathLengthBound)
                        {
                            break;
                        }

                        //到达终点则记录路径的长度,并计算出搜索范围
                        if (currentPosition_Connected == currentLevelAncestorPartOfStartPosition)
                        {
                            if (PathLengthBound == float.MaxValue)
                            {
                                PathLengthBound = CalculatePathLengthBound(m2mStructure.GetLevelNum(), levelSequence, TagOfCurrentPart_Connected.ge);
                            }
                        }

                        TagOfCurrentPart_Connected.isClose = true;

                        IPositionSet_Connected_Adjacency CurrentPartAdjSet = currentPosition_Connected.GetAdjacencyPositionSet();
                        CurrentPartAdjSet.InitToTraverseSet();
                        while (CurrentPartAdjSet.NextPosition())
                        {
                            IPart_Connected adjPosition      = (IPart_Connected)CurrentPartAdjSet.GetPosition_Connected();
                            Tag_M2M_Part    tagOfAdjPosition = (Tag_M2M_Part)adjPosition.GetAttachment();

                            bool isInSearchingBound = false;

                            if (isTopLevel)
                            {
                                isInSearchingBound = true;
                            }
                            else
                            {
                                Tag_M2M_Part parenPartTag = (Tag_M2M_Part)adjPosition.GetParentPart().GetAttachment();
                                if ((parenPartTag.timeStamp == lastLevelTimeStamp) && (parenPartTag.isNeedToSearch == true))
                                {
                                    isInSearchingBound = true;
                                }
                            }

                            //如果属于搜索空间
                            if (isInSearchingBound)
                            {
                                //如果未被搜索
                                if (tagOfAdjPosition.timeStamp != endTime_stamp)
                                {
                                    float newG = TagOfCurrentPart_Connected.ge + CurrentPartAdjSet.GetDistanceToAdjacency();

                                    if (newG < PathLengthBound)
                                    {
                                        tagOfAdjPosition.ge        = newG;
                                        tagOfAdjPosition.isClose   = false;
                                        tagOfAdjPosition.timeStamp = endTime_stamp;
                                        open.add(adjPosition);
                                    }
                                }
                                else
                                {
                                    if (!tagOfAdjPosition.isClose)
                                    {
                                        float newG = TagOfCurrentPart_Connected.ge + CurrentPartAdjSet.GetDistanceToAdjacency();
                                        if (newG < tagOfAdjPosition.ge)
                                        {
                                            tagOfAdjPosition.ge = newG;
                                            open.update(adjPosition);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    startTime_stamp = TimeStamp.getNextTimeStamp(endTime_stamp);

                    StartPartTag.timeStamp = startTime_stamp;
                    StartPartTag.gs        = 0;

                    open.clear();
                    ((M2M_Part_TagComparer)com).state = 1;

                    //将起点加入open表
                    open.add(currentLevelAncestorPartOfStartPosition);

                    //当open表非空时
                    while (open.getSize() > 0)
                    {
                        //获得下一个最近的点
                        IPart_Connected currentPosition_Connected  = (IPart_Connected)open.removeFirst();
                        Tag_M2M_Part    TagOfCurrentPart_Connected = (Tag_M2M_Part)currentPosition_Connected.GetAttachment();

                        //当open表里面所有的点的g值都超出路径最大长度范围,则结束循环
                        if (TagOfCurrentPart_Connected.gs >= PathLengthBound)
                        {
                            break;
                        }

                        TagOfCurrentPart_Connected.isClose = true;

                        IPositionSet_Connected_Adjacency CurrentPartAdjSet = currentPosition_Connected.GetAdjacencyPositionSet();
                        CurrentPartAdjSet.InitToTraverseSet();
                        while (CurrentPartAdjSet.NextPosition())
                        {
                            IPart_Connected adjPosition      = (IPart_Connected)CurrentPartAdjSet.GetPosition_Connected();
                            Tag_M2M_Part    tagOfAdjPosition = (Tag_M2M_Part)adjPosition.GetAttachment();

                            bool isInSearchingBound = false;
                            if (isTopLevel)
                            {
                                isInSearchingBound = true;
                            }
                            else
                            {
                                Tag_M2M_Part parenPartTag = (Tag_M2M_Part)adjPosition.GetParentPart().GetAttachment();

                                if ((parenPartTag.timeStamp == lastLevelTimeStamp) && (parenPartTag.isNeedToSearch == true))
                                {
                                    isInSearchingBound = true;
                                }
                            }

                            //如果属于搜索空间
                            if (isInSearchingBound)
                            {
                                //如果未被搜索
                                if (tagOfAdjPosition.timeStamp != startTime_stamp)
                                {
                                    float newG = TagOfCurrentPart_Connected.gs + CurrentPartAdjSet.GetDistanceToAdjacency();

                                    if (newG < PathLengthBound)
                                    {
                                        tagOfAdjPosition.gs      = newG;
                                        tagOfAdjPosition.isClose = false;

                                        //如果在上面的搜索过程中被搜索过
                                        if (tagOfAdjPosition.timeStamp == endTime_stamp)
                                        {
                                            //如果两次搜索的g值之和小于路径的最大长度则标记该分块为下一层的待搜索空间
                                            if (tagOfAdjPosition.ge + newG < PathLengthBound)
                                            {
                                                tagOfAdjPosition.isNeedToSearch = true;
                                            }
                                            else
                                            {
                                                tagOfAdjPosition.isNeedToSearch = false;
                                            }
                                        }
                                        else
                                        {
                                            //如果在上面的搜索过程中没有被搜索过,则把它的ge值设大,使得以后改变g值的时候不会因为两个g值之和小于PathLengthBound而把该点标记为待搜索点
                                            tagOfAdjPosition.ge             = PathLengthBound + 1;
                                            tagOfAdjPosition.isNeedToSearch = false;
                                        }

                                        tagOfAdjPosition.timeStamp = startTime_stamp;

                                        open.add(adjPosition);
                                    }
                                }
                                else
                                {
                                    if (!tagOfAdjPosition.isClose)
                                    {
                                        float newG = TagOfCurrentPart_Connected.gs + CurrentPartAdjSet.GetDistanceToAdjacency();
                                        if (newG < tagOfAdjPosition.gs)
                                        {
                                            if (tagOfAdjPosition.isNeedToSearch == false)
                                            {
                                                //如果两次搜索的g值之和小于路径的最大长度则标记该分块为下一层的待搜索空间
                                                if (tagOfAdjPosition.ge + newG < PathLengthBound)
                                                {
                                                    tagOfAdjPosition.isNeedToSearch = true;
                                                }
                                            }

                                            tagOfAdjPosition.gs = newG;
                                            open.update(adjPosition);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    lastLevelTimeStamp = startTime_stamp;
                    if (GetTimeStamp != null)
                    {
                        GetTimeStamp(lastLevelTimeStamp);
                    }
                }
            }

            if (GetM2MStructure != null)
            {
                GetM2MStructure(m2mStructure);
            }

            //最底层寻找真实路径

            path.Clear();
            ((M2M_Part_TagComparer)com).state = 2;

            if (end == start)
            {
                path.Add(end);
                return(path);
            }

            //判断起点和终点是否在地图上,并初始化起点的标签
            Tag_M2M_Position tag = (Tag_M2M_Position)end.GetAttachment();

            //生成这次寻径使用的time stamp
            time_stamp = TimeStamp.getNextTimeStamp(lastLevelTimeStamp);

            if (tag != null)
            {
                tag.g         = 0;
                tag.parent    = null;
                tag.isClose   = false;
                tag.timeStamp = time_stamp;
            }

            IPosition_Connected p = null, p_adj;
            IPositionSet_Connected_Adjacency adj_set;
            Tag_M2M_Position p_tag, p_adj_tag;

            open.clear();

            //将起点加入open表
            open.add(end);

            //当open表非空时
            while (open.getSize() > 0)
            {
                float newG;

                //获得下一个最近的点
                p = open.removeFirst();
                //到达终点则结束
                if (p == start)
                {
                    pathLength = ((Tag_M2M_Position)start.GetAttachment()).g;
                    break;
                }
                p_tag         = (Tag_M2M_Position)p.GetAttachment();
                p_tag.isClose = true;
                adj_set       = p.GetAdjacencyPositionSet();
                adj_set.InitToTraverseSet();

                while (adj_set.NextPosition())
                {
                    p_adj     = adj_set.GetPosition_Connected();
                    p_adj_tag = (Tag_M2M_Position)p_adj.GetAttachment();

                    //如果需要搜索
                    Tag_M2M_Part parentPartTag = (Tag_M2M_Part)p_adj_tag.parentPart.GetAttachment();
                    if (parentPartTag.isNeedToSearch && parentPartTag.timeStamp == lastLevelTimeStamp)
                    {
                        //如果未被搜索
                        if (p_adj_tag.timeStamp != time_stamp)
                        {
                            newG = p_tag.g + adj_set.GetDistanceToAdjacency();

                            p_adj_tag.parent    = p;
                            p_adj_tag.g         = newG;
                            p_adj_tag.isClose   = false;
                            p_adj_tag.timeStamp = time_stamp;
                            open.add(p_adj);
                        }
                        else
                        {
                            if (!p_adj_tag.isClose)
                            {
                                newG = p_tag.g + adj_set.GetDistanceToAdjacency();
                                if (newG < p_adj_tag.g)
                                {
                                    p_adj_tag.parent = p;
                                    p_adj_tag.g      = newG;
                                    open.update(p_adj);
                                }
                            }
                        }
                    }
                }
            }



            //从终点根据标签中记录的父节点找到起点,生成路径
            if (p == start)
            {
                path.Add(start);
                p_tag = (Tag_M2M_Position)start.GetAttachment();
                while (p_tag.parent != null)
                {
                    path.Add(p_tag.parent);
                    p_tag = (Tag_M2M_Position)p_tag.parent.GetAttachment();
                }
                //path.Reverse();
                return(path);
            }
            else
            {
                return(null);
            }
        }
        private void BFSInOnePoint(Queue <PositionAndPositon> PositionAndPositonQueue, bool isPart, List <IPart_Connected> SubPartList, IPart_Multi currentMultiPart, float minSequenceX, float maxSequenceX, float minSequenceY, float maxSequenceY, IPosition_Connected currentPosition_Connected)
        {
            //如果没有被搜索
            if (GetParentPart(currentPosition_Connected, isPart) == null)
            {
                IPart_Connected currentPart_Connected = currentMultiPart.CreateSubPart();
                currentPart_Connected.SetAttachment(new Tag_M2M_Part());
                currentPart_Connected.SetX(currentMultiPart.GetX());
                currentPart_Connected.SetY(currentMultiPart.GetY());
                bool isNeedToAddToSubPartList;// = true;
                SubPartList.Add(currentPart_Connected);

                currentPart_Connected.AddToSubPositionList(currentPosition_Connected);
                SetParentPart(currentPosition_Connected, currentPart_Connected, isPart);

                //以当前点为起始点做墨滴搜索
                Queue <IPosition_Connected> OpenTable = new Queue <IPosition_Connected>();

                OpenTable.Enqueue(currentPosition_Connected);

                //如果Open表还有元素则继续取出
                while (OpenTable.Count > 0)
                {
                    IPosition_Connected currentCenterPosition_Connected = OpenTable.Dequeue();
                    IPositionSet_Connected_Adjacency currentPositionAdjacencyPositionSet = currentCenterPosition_Connected.GetAdjacencyPositionSet();

                    currentPositionAdjacencyPositionSet.InitToTraverseSet();

                    while (currentPositionAdjacencyPositionSet.NextPosition())
                    {
                        IPosition_Connected adjPosition_Connected = currentPositionAdjacencyPositionSet.GetPosition_Connected();

                        float pX = adjPosition_Connected.GetX();
                        float pY = adjPosition_Connected.GetY();
                        //如果分块在当前分块之内
                        if (pX >= minSequenceX && pX < maxSequenceX && pY >= minSequenceY && pY < maxSequenceY)
                        {
                            IPart_Connected parentPart = GetParentPart(adjPosition_Connected, isPart);
                            //如果该分块还没被搜索
                            if (parentPart == null)
                            {
                                currentPart_Connected.AddToSubPositionList(adjPosition_Connected);
                                SetParentPart(adjPosition_Connected, currentPart_Connected, isPart);

                                //放进Open表
                                OpenTable.Enqueue(adjPosition_Connected);
                            }
                            //如果父分块不为null,则表明该分块之前已经被搜索过,刚搜索到的分块与原分块连通
                            else if (parentPart != currentPart_Connected)
                            {
                                isNeedToAddToSubPartList = false;
                                //把原来的父分块设为新的父分块

                                IPositionSet tempPositionSet = parentPart.GetTrueChildPositionSet();
                                tempPositionSet.InitToTraverseSet();
                                while (tempPositionSet.NextPosition())
                                {
                                    IPosition_Connected temp = (IPosition_Connected)tempPositionSet.GetPosition();

                                    SetParentPart(temp, currentPart_Connected, isPart);
                                    currentPart_Connected.AddToSubPositionList(temp);
                                }

                                SubPartList.Remove(parentPart);
                            }
                        }
                        //如果不在当前分块里面
                        else
                        {
                            //如果在当前分块外的点还没被搜索(即还没被制定其父分块)则把其放进partAndPositonQueue
                            IPart_Connected currentParentPart = GetParentPart(adjPosition_Connected, isPart);

                            PositionAndPositonQueue.Enqueue(new PositionAndPositon(currentCenterPosition_Connected, adjPosition_Connected));

                            //if (currentParentPart == null)
                            //{
                            //    PositionAndPositonQueue.Enqueue(new PositionAndPositon(currentCenterPosition_Connected, adjPosition_Connected));
                            //}
                            ////如果在当前分块外的点已经分配父分块,则建立两父分块间的链接关系。
                            //else
                            //{
                            //    currentPart_Connected.GetAdjacencyPositionSetEdit().AddAdjacency(currentParentPart, CalculateTheDistanceBetweenTwoPosition(currentPart_Connected, currentParentPart));
                            //}
                        }
                    }
                }
            }
        }