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); }
//没有路径则返回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)); //} } } } } }