mirror of
https://github.com/Wessel/Roommapper.git
synced 2026-07-20 23:13:57 +02:00
Added PathPlanner to cover an area using Astar
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
namespace RoutePlanner
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
150
src/CoveragePathPlanner/CoveragePathPlanner.cs
Normal file
150
src/CoveragePathPlanner/CoveragePathPlanner.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
public class CoveragePathPlanner
|
||||
{
|
||||
private int _width;
|
||||
private int _height;
|
||||
private List<Cell> _cells;
|
||||
|
||||
public CoveragePathPlanner(int width, int height)
|
||||
{
|
||||
_width = width;
|
||||
_height = height;
|
||||
_cells = new List<Cell>();
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
_cells.Add(new Cell { X = x, Y = y, IsObstacle = false, IsVisited = false, Cost = double.MaxValue });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Point> PlanPath(List<Obstacle> obstacles)
|
||||
{
|
||||
// Add obstacles to the grid
|
||||
foreach (Obstacle obstacle in obstacles)
|
||||
{
|
||||
for (int x = obstacle.X; x < obstacle.X + obstacle.Width; x++)
|
||||
{
|
||||
for (int y = obstacle.Y; y < obstacle.Y + obstacle.Height; y++)
|
||||
{
|
||||
_cells[x + y * _width].IsObstacle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the start cell
|
||||
Cell startCell = _cells[0];
|
||||
startCell.Cost = 0;
|
||||
|
||||
// Create a priority queue to hold the cells to be processed
|
||||
var queue = new PriorityQueue<Cell, double>();
|
||||
queue.Enqueue(startCell, 0);
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
// Dequeue the cell with the lowest cost
|
||||
Cell currentCell = queue.Dequeue();
|
||||
|
||||
// If the cell is the goal, construct the path
|
||||
if (currentCell.X == _width - 1 && currentCell.Y == _height - 1)
|
||||
{
|
||||
List<Point> path = new List<Point>();
|
||||
while (currentCell != null)
|
||||
{
|
||||
path.Add(new Point(currentCell.X, currentCell.Y));
|
||||
currentCell = currentCell.Parent;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
// Mark the cell as visited
|
||||
currentCell.IsVisited = true;
|
||||
|
||||
// Explore the neighbors
|
||||
foreach (Cell neighbor in GetNeighbors(currentCell))
|
||||
{
|
||||
if (!neighbor.IsVisited && !neighbor.IsObstacle)
|
||||
{
|
||||
// Calculate the cost of the neighbor
|
||||
double cost = currentCell.Cost + 1;
|
||||
if (cost < neighbor.Cost)
|
||||
{
|
||||
neighbor.Cost = cost;
|
||||
neighbor.Parent = currentCell;
|
||||
queue.Enqueue(neighbor, cost + Heuristic(neighbor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no path is found, return an empty list
|
||||
return new List<Point>();
|
||||
}
|
||||
|
||||
private List<Cell> GetNeighbors(Cell cell)
|
||||
{
|
||||
List<Cell> neighbors = new List<Cell>();
|
||||
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
for (int y = -1; y <= 1; y++)
|
||||
{
|
||||
if (x == 0 && y == 0) continue;
|
||||
|
||||
int neighborX = cell.X + x;
|
||||
int neighborY = cell.Y + y;
|
||||
|
||||
if (neighborX >= 0 && neighborX < _width && neighborY >= 0 && neighborY < _height)
|
||||
{
|
||||
neighbors.Add(_cells[neighborX + neighborY * _width]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
private double Heuristic(Cell cell)
|
||||
{
|
||||
// Manhattan distance heuristic
|
||||
return Math.Abs(cell.X - (_width - 1)) + Math.Abs(cell.Y - (_height - 1));
|
||||
}
|
||||
|
||||
public List<Point> test()
|
||||
{
|
||||
CoveragePathPlanner planner = new CoveragePathPlanner(500, 500);
|
||||
|
||||
List<Obstacle> obstacles = new List<Obstacle>
|
||||
{
|
||||
new Obstacle { X = 100, Y = 100, Width = 50, Height = 50 },
|
||||
new Obstacle { X = 200, Y = 200, Width = 100, Height = 100 },
|
||||
new Obstacle { X = 300, Y = 300, Width = 150, Height = 150 }
|
||||
};
|
||||
|
||||
return planner.PlanPath(obstacles);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class Obstacle
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
}
|
||||
|
||||
public class Cell
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public bool IsObstacle { get; set; }
|
||||
public bool IsVisited { get; set; }
|
||||
public double Cost { get; set; }
|
||||
public Cell Parent { get; set; }
|
||||
}
|
||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.9.34723.18
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoutePlanner", "RoutePlanner.csproj", "{88355634-1B39-4827-BF30-7F28679F9F29}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoveragePathPlanner", "CoveragePathPlanner.csproj", "{19337BCA-6374-4DAE-90D4-38CF1D236D30}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -11,15 +11,15 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{88355634-1B39-4827-BF30-7F28679F9F29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{88355634-1B39-4827-BF30-7F28679F9F29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{88355634-1B39-4827-BF30-7F28679F9F29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{88355634-1B39-4827-BF30-7F28679F9F29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{19337BCA-6374-4DAE-90D4-38CF1D236D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{19337BCA-6374-4DAE-90D4-38CF1D236D30}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19337BCA-6374-4DAE-90D4-38CF1D236D30}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19337BCA-6374-4DAE-90D4-38CF1D236D30}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {34DA189D-30EE-4764-9FA7-E0231AAB553B}
|
||||
SolutionGuid = {45198B26-DA54-465D-98BD-3568A4250889}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user