/** * 判断能否从当前cell走到下一个cell * @param startCell * @param nextCell * @return */ private bool canWalkToNextCell(Point startCell, Point nextCell) { // 下一个点在阻挡区域,直接不可达 if (AStarCell.isObstacle(map.getCell(nextCell.x, nextCell.y))) { return(false); } // 下一个cell是前一个cell的上下左右的cell,可达 if (startCell.x == nextCell.x || startCell.y == nextCell.y) { return(true); } // 否则是对角cell,判断法向对角的两个cell是否都在阻挡区域,如果是则不可达 if (AStarCell.isObstacle(map.getCell(startCell.x, nextCell.y)) && AStarCell.isObstacle(map.getCell(nextCell.x, startCell.y))) { return(false); } else { return(true); } }
/** * Bresenham line algorithm * @param start * @param goal * @return */ public Point raycast(Vector2 startPos, Vector2 goalPos, float cellSize) { Point startCell = posToCell(startPos, cellSize); Point goalCell = posToCell(goalPos, cellSize); // exception: start is obstacle. Now just return start if (AStarCell.isObstacle(map.getCell(startCell.x, startCell.y))) { return(startCell); } if (startCell.Equals(goalCell)) { return(startCell); } float diffx = goalPos.x - startPos.x; float diffy = goalPos.y - startPos.y; float distanceSquare = diffx * diffx + diffy * diffy; float distance = (float)Math.Sqrt(distanceSquare); Vector2 dir = new Vector2(diffx / distance, diffy / distance); Vector2 lastPassed = startPos; Point hitPoint = new Point(startCell.x, startCell.y); while (true) { Vector2 nextPos = getNextPos(lastPassed, dir, cellSize); Point newCell = posToCell(nextPos, cellSize); float dis = (nextPos.x - startPos.x) * (nextPos.x - startPos.x) + (nextPos.y - startPos.y) * (nextPos.y - startPos.y); if (dis >= distanceSquare) { break; } if (!canWalkToNextCell(hitPoint, newCell)) { break; } else { hitPoint.x = newCell.x; hitPoint.y = newCell.y; if (newCell.Equals(goalCell)) { break; } } lastPassed = nextPos; } return(hitPoint); }
public PrintMap(AStarMap map, List <Point> shortestPath) { StringBuilder sb = new StringBuilder(); AStarCell cell; for (int y = 0; y < map.getHeightInCells(); y++) { if (y == 0) { for (int i = 0; i <= map.getHeightInCells(); i++) { sb.Append("-"); } sb.AppendLine(); } sb.Append("|"); for (int x = 0; x < map.getWidthInCells(); x++) { cell = map.getCell(x, y); if (AStarCell.isObstacle(cell)) { sb.Append("X"); } else if (isStart(shortestPath, cell.getPoint())) { sb.Append("s"); } else if (isGoal(shortestPath, cell.getPoint())) { sb.Append("g"); } else if (contains(shortestPath, cell.getPoint())) { sb.Append("?"); } else { sb.Append(" "); } if (y == map.getHeightInCells()) { sb.Append("_"); } } sb.Append("|"); sb.AppendLine(); } for (int i = 0; i <= map.getHeightInCells(); i++) { sb.Append("-"); } //System.Console.SetWindowSize(System.Console.LargestWindowWidth, System.Console.LargestWindowHeight); //System.Console.Write(sb.ToString()); }
private bool lineClear(Point a, Point b) { List <Point> pointsOnLine = Bresenham.getCellsOnLine(a, b); foreach (Point p in pointsOnLine) { AStarCell cell = map.getCell(p.x, p.y); if (cell == null || cell.isObstacle()) { return(false); } } return(true); }
public Point raycast(Point start, Point goal) { List <Point> pointsOnLine = Bresenham.getCellsOnLine(start, goal); Point hitPoint = (Point)start.Clone(); foreach (Point p in pointsOnLine) { AStarCell cell = map.getCell(p.x, p.y); if (cell == null || cell.isObstacle()) { break; } else { hitPoint = p; } } return(hitPoint); }
public Vector2 Raycast(Vector2 startPos, Vector2 endPos) { Point startCell = PathFinder.posToCell(startPos, astarMap.getCellSize()); Point goalCell = PathFinder.posToCell(endPos, astarMap.getCellSize()); // exception: start is obstacle. Now just return start if (AStarCell.isObstacle(astarMap.getCell(startCell.x, startCell.y))) { return(startPos); } if (startCell.Equals(goalCell)) { return(endPos); } Point hitCell = pathFinder.raycast(startPos, endPos, astarMap.getCellSize()); Vector2 hitPos = PathFinder.cellToPos(hitCell, astarMap.getCellSize()); Vector2 dir = (endPos - startPos).normalized; hitPos = PathFinder.getNextPosBeforeNextCell(hitPos, dir, astarMap.getCellSize()); return(hitPos); }
public Point getCellWithErrorTolerate(float x, float y) { int cellX = (int)Math.Floor((x + map.getErrorTolerate()) / map.getCellSize()); int cellY = (int)Math.Floor((y + map.getErrorTolerate()) / map.getCellSize()); AStarCell cell = map.getCell(cellX, cellY); if (!AStarCell.isObstacle(cell)) { return(new Point(cellX, cellY)); } cellX = (int)Math.Floor((x - map.getErrorTolerate()) / map.getCellSize()); cellY = (int)Math.Floor((y - map.getErrorTolerate()) / map.getCellSize()); cell = map.getCell(cellX, cellY); if (!AStarCell.isObstacle(cell)) { return(new Point(cellX, cellY)); } cellX = (int)Math.Floor((x + map.getErrorTolerate()) / map.getCellSize()); cellY = (int)Math.Floor((y - map.getErrorTolerate()) / map.getCellSize()); cell = map.getCell(cellX, cellY); if (!AStarCell.isObstacle(cell)) { return(new Point(cellX, cellY)); } cellX = (int)Math.Floor((x - map.getErrorTolerate()) / map.getCellSize()); cellY = (int)Math.Floor((y + map.getErrorTolerate()) / map.getCellSize()); cell = map.getCell(cellX, cellY); if (!AStarCell.isObstacle(cell)) { return(new Point(cellX, cellY)); } return(null); }