private List <PathFinderNode> OrderClosedListAsPath(Point end) { _closed.Clear(); var fNodeTmp = _mCalcGrid[(end.Y << _gridYLog2) + end.X]; var fNode = new PathFinderNode { F = fNodeTmp.F, G = fNodeTmp.G, H = 0, Px = fNodeTmp.PX, Py = fNodeTmp.PY, X = end.X, Y = end.Y }; while (fNode.X != fNode.Px || fNode.Y != fNode.Py) { _closed.Add(fNode); var posX = fNode.Px; var posY = fNode.Py; fNodeTmp = _mCalcGrid[(posY << _gridYLog2) + posX]; fNode.F = fNodeTmp.F; fNode.G = fNodeTmp.G; fNode.H = 0; fNode.Px = fNodeTmp.PX; fNode.Py = fNodeTmp.PY; fNode.X = posX; fNode.Y = posY; } _closed.Add(fNode); return(_closed); }
private List <PathFinderNode> OrderClosedListAsPath(Point end) { _closed.Clear(); var fNodeTmp = _mCalcGrid[end.X, end.Y]; var fNode = new PathFinderNode { F_Gone_Plus_Heuristic = fNodeTmp.F_Gone_Plus_Heuristic, Gone = fNodeTmp.Gone, Heuristic = 0, ParentX = fNodeTmp.ParentX, ParentY = fNodeTmp.ParentY, X = end.X, Y = end.Y }; while (fNode.X != fNode.ParentX || fNode.Y != fNode.ParentY) { _closed.Add(fNode); var posX = fNode.ParentX; var posY = fNode.ParentY; fNodeTmp = _mCalcGrid[posX, posY]; fNode.F_Gone_Plus_Heuristic = fNodeTmp.F_Gone_Plus_Heuristic; fNode.Gone = fNodeTmp.Gone; fNode.Heuristic = 0; fNode.ParentX = fNodeTmp.ParentX; fNode.ParentY = fNodeTmp.ParentY; fNode.X = posX; fNode.Y = posY; } _closed.Add(fNode); return(_closed); }
public List <PathFinderNode> FindPath(Point start, Point end) { HighResolutionTime.Start(); PathFinderNode parentNode; bool found = false; int gridX = mGrid.GetUpperBound(0); int gridY = mGrid.GetUpperBound(1); mStop = false; mStopped = false; mOpen.Clear(); mClose.Clear(); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, start.X, start.Y, PathFinderNodeType.Start, -1, -1); } if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, end.X, end.Y, PathFinderNodeType.End, -1, -1); } #endif sbyte[,] direction; if (mDiagonals) { direction = new sbyte[8, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } } } ; else { direction = new sbyte[4, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } } }; parentNode.G = 0; parentNode.H = mHEstimate; parentNode.F = parentNode.G + parentNode.H; parentNode.X = start.X; parentNode.Y = start.Y; parentNode.PX = parentNode.X; parentNode.PY = parentNode.Y; mOpen.Push(parentNode); while (mOpen.Count > 0 && !mStop) { parentNode = mOpen.Pop(); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, parentNode.X, parentNode.Y, PathFinderNodeType.Current, -1, -1); } #endif if (parentNode.X == end.X && parentNode.Y == end.Y) { mClose.Add(parentNode); found = true; break; } if (mClose.Count > mSearchLimit) { mStopped = true; return(null); } if (mPunishChangeDirection) { mHoriz = (parentNode.X - parentNode.PX); } //Lets calculate each successors for (int i = 0; i < (mDiagonals ? 8 : 4); i++) { PathFinderNode newNode; newNode.X = parentNode.X + direction[i, 0]; newNode.Y = parentNode.Y + direction[i, 1]; if (newNode.X < 0 || newNode.Y < 0 || newNode.X >= gridX || newNode.Y >= gridY) { continue; } int newG; if (mHeavyDiagonals && i > 3) { newG = parentNode.G + (int)(mGrid[newNode.X, newNode.Y] * 2.41); } else { newG = parentNode.G + mGrid[newNode.X, newNode.Y]; } if (newG == parentNode.G) { //Unbrekeable continue; } if (mPunishChangeDirection) { if ((newNode.X - parentNode.X) != 0) { if (mHoriz == 0) { newG += 20; } } if ((newNode.Y - parentNode.Y) != 0) { if (mHoriz != 0) { newG += 20; } } } int foundInOpenIndex = -1; for (int j = 0; j < mOpen.Count; j++) { if (mOpen[j].X == newNode.X && mOpen[j].Y == newNode.Y) { foundInOpenIndex = j; break; } } if (foundInOpenIndex != -1 && mOpen[foundInOpenIndex].G <= newG) { continue; } int foundInCloseIndex = -1; for (int j = 0; j < mClose.Count; j++) { if (mClose[j].X == newNode.X && mClose[j].Y == newNode.Y) { foundInCloseIndex = j; break; } } if (foundInCloseIndex != -1 && mClose[foundInCloseIndex].G <= newG) { continue; } newNode.PX = parentNode.X; newNode.PY = parentNode.Y; newNode.G = newG; switch (mFormula) { default: case HeuristicFormula.Manhattan: newNode.H = mHEstimate * (Math.Abs(newNode.X - end.X) + Math.Abs(newNode.Y - end.Y)); break; case HeuristicFormula.MaxDXDY: newNode.H = mHEstimate * (Math.Max(Math.Abs(newNode.X - end.X), Math.Abs(newNode.Y - end.Y))); break; case HeuristicFormula.DiagonalShortCut: int h_diagonal = Math.Min(Math.Abs(newNode.X - end.X), Math.Abs(newNode.Y - end.Y)); int h_straight = (Math.Abs(newNode.X - end.X) + Math.Abs(newNode.Y - end.Y)); newNode.H = (mHEstimate * 2) * h_diagonal + mHEstimate * (h_straight - 2 * h_diagonal); break; case HeuristicFormula.Euclidean: newNode.H = (int)(mHEstimate * Math.Sqrt(Math.Pow((newNode.X - end.X), 2) + Math.Pow((newNode.Y - end.Y), 2))); break; case HeuristicFormula.EuclideanNoSQR: newNode.H = (int)(mHEstimate * (Math.Pow((newNode.X - end.X), 2) + Math.Pow((newNode.Y - end.Y), 2))); break; case HeuristicFormula.Custom1: Point dxy = new Point(Math.Abs(end.X - newNode.X), Math.Abs(end.Y - newNode.Y)); int Orthogonal = Math.Abs(dxy.X - dxy.Y); int Diagonal = Math.Abs(((dxy.X + dxy.Y) - Orthogonal) / 2); newNode.H = mHEstimate * (Diagonal + Orthogonal + dxy.X + dxy.Y); break; } if (mTieBreaker) { int dx1 = parentNode.X - end.X; int dy1 = parentNode.Y - end.Y; int dx2 = start.X - end.X; int dy2 = start.Y - end.Y; int cross = Math.Abs(dx1 * dy2 - dx2 * dy1); newNode.H = (int)(newNode.H + cross * 0.001); } newNode.F = newNode.G + newNode.H; #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(parentNode.X, parentNode.Y, newNode.X, newNode.Y, PathFinderNodeType.Open, newNode.F, newNode.G); } #endif //It is faster if we leave the open node in the priority queue //When it is removed, all nodes around will be closed, it will be ignored automatically //if (foundInOpenIndex != -1) // mOpen.RemoveAt(foundInOpenIndex); //if (foundInOpenIndex == -1) mOpen.Push(newNode); } mClose.Add(parentNode); #if DEBUGON if (mDebugProgress && PathFinderDebug != null) { PathFinderDebug(0, 0, parentNode.X, parentNode.Y, PathFinderNodeType.Close, parentNode.F, parentNode.G); } #endif } mCompletedTime = HighResolutionTime.GetTime(); if (found) { PathFinderNode fNode = mClose[mClose.Count - 1]; for (int i = mClose.Count - 1; i >= 0; i--) { if (fNode.PX == mClose[i].X && fNode.PY == mClose[i].Y || i == mClose.Count - 1) { #if DEBUGON if (mDebugFoundPath && PathFinderDebug != null) { PathFinderDebug(fNode.X, fNode.Y, mClose[i].X, mClose[i].Y, PathFinderNodeType.Path, mClose[i].F, mClose[i].G); } #endif fNode = mClose[i]; } else { mClose.RemoveAt(i); } } mStopped = true; return(mClose); } mStopped = true; return(null); }
public Vector3d P2V(AStar.PathFinderNode p) { return(new Vector3d(FixedMath.One * p.X * Size / 100, 0, FixedMath.One * p.Y * Size / 100) + new Vector3d(FixedMath.One * (int)Offset.x / 100, 0, FixedMath.One * (int)Offset.y / 100)); }
Vector3 p2v(AStar.PathFinderNode p) { return(JPSAStar.active.P2V(p).ToVector3()); }