- 积分
- 1905
- 明经币
- 个
- 注册时间
- 2022-4-4
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 枫叶棋语 于 2024-1-17 23:08 编辑
- using CsCad.Collections;
- using CsCad.FlashDraw;
- using static CsCad.Draw.DrawEntity;
- namespace CsCad.PathSearch
- {
- public class Edge2D
- {
- public Point2d StartPoint;
- public Point2d EndPoint;
- public double Dist;
- public Polyline Polyline;
- public Edge2D(Line line)
- {
- this.StartPoint = new Point2d(Math.Round( line.StartPoint.X,3),Math.Round( line.StartPoint.Y,3));
- this.EndPoint = new Point2d(Math.Round( line.EndPoint.X,3),Math.Round( line.EndPoint.Y,3));
- //this.Dist = Math.Abs(this.StartPoint.X - this.EndPoint.X) + Math.Abs(this.StartPoint.Y - this.EndPoint.Y);
- this.Dist = this.StartPoint.GetDistanceTo(this.EndPoint);
- this.Polyline = CreatePolyline(this.StartPoint, this.EndPoint);
- this.Polyline.ColorIndex = 8;
- }
- public Edge2D(Point2d start, Point2d end)
- {
- this.StartPoint = new Point2d(Math.Round(start.X, 3), Math.Round(start.Y, 3));
- this.EndPoint = new Point2d(Math.Round(end.X, 3), Math.Round(end.Y, 3));
- //this.Dist = Math.Abs(this.StartPoint.X - this.EndPoint.X) + Math.Abs(this.StartPoint.Y - this.EndPoint.Y);
- this.Dist = this.StartPoint.GetDistanceTo(this.EndPoint);
- this.Polyline = CreatePolyline(this.StartPoint, this.EndPoint);
- this.Polyline.ColorIndex = 8;
- }
- public Edge2D(Point3d start, Point3d end)
- {
- this.StartPoint = new Point2d(Math.Round(start.X, 3), Math.Round(start.Y, 3));
- this.EndPoint = new Point2d(Math.Round(end.X, 3), Math.Round(end.Y, 3));
- //this.Dist = Math.Abs(this.StartPoint.X - this.EndPoint.X) + Math.Abs(this.StartPoint.Y - this.EndPoint.Y);
- this.Dist = this.StartPoint.GetDistanceTo(this.EndPoint);
- this.Polyline = CreatePolyline(this.StartPoint, this.EndPoint);
- this.Polyline.ColorIndex = 8;
- }
- public Point2d? GetNeighbor(Point2d current)
- {
- if (current == StartPoint)
- {
- return EndPoint;
- }
- else if (current == EndPoint)
- {
- return StartPoint;
- }
- else
- {
- return null;
- }
- }
- public override string ToString()
- {
- return $"[{this.StartPoint},{this.EndPoint}]";
- }
- }
- public class Graphs2D
- {
- public DefaultDict<Point2d, HashSet<Edge2D>> Pairs;
- public Flash Flash;
- public List<Polyline> pls = new List<Polyline>();
- public Graphs2D(HashSet<Line> lines)
- {
- this.Pairs = new DefaultDict<Point2d, HashSet<Edge2D>>();
- Flash = new Flash();
- var edges = lines.Select(line => new Edge2D(line)).ToList();
- foreach (Edge2D edge in edges)
- {
- this.Pairs[edge.StartPoint].Add(edge);
- this.Pairs[edge.EndPoint].Add(edge);
- }
- }
- public Graphs2D(HashSet<Edge2D> edges)
- {
- this.Pairs = new DefaultDict<Point2d, HashSet<Edge2D>>();
- Flash = new Flash();
- foreach (Edge2D edge in edges)
- {
- this.Pairs[edge.StartPoint].Add(edge);
- this.Pairs[edge.EndPoint].Add(edge);
- }
- }
- public Graphs2D()
- {
- this.Pairs = new DefaultDict<Point2d, HashSet<Edge2D>>();
- Flash = new Flash();
- }
- public void AddEdge(Edge2D edge)
- {
- this.Pairs[edge.StartPoint].Add(edge);
- this.Pairs[edge.EndPoint].Add(edge);
- }
- public void AddLine(Line line)
- {
- var edge = new Edge2D(line);
- AddEdge(edge);
- }
- public List<Point2d> AstarSearch(Point2d start, Point2d end)
- {
- start = new Point2d(Math.Round(start.X, 3), Math.Round(start.Y, 3));
- end = new Point2d(Math.Round(end.X, 3), Math.Round(end.Y, 3));
- List<Point2d> path = new List<Point2d>();
- PriorityQueue2D<Point2d> queue = new PriorityQueue2D<Point2d>();
- Dictionary<Point2d, Point2d> previous = new Dictionary<Point2d, Point2d>();
- Dictionary<Point2d, double> distance = new Dictionary<Point2d, double>();
- queue.Enqueue(start, 0);
- distance[start] = 0;
- var pl = new Polyline();
- pl.ColorIndex = 1;
- if (!Pairs.ContainsKey(start) || !Pairs.ContainsKey(end))
- {
- // 起点或终点不在Pairs的key里面,返回空路径
- Print(Pairs.ContainsKey(start), Pairs.ContainsKey(end));
- Flash.Clear();
- return path;
- }
- while (queue.Count > 0)
- {
- Point2d current = queue.Dequeue();
- int vertext = 0;
- if (current.Equals(end))
- {
- Flash.Clear();
- Flash.Update(pl);
- path.Add(current);
- pl.AddVertexAt(vertext, current, 0, 0, 0);
- while (previous.ContainsKey(current))
- {
- current = previous[current];
- vertext++;
- pl.AddVertexAt(vertext, current, 0, 0, 0);
- Flash.Update(pl, 1);
- path.Insert(0, current);
- }
- Flash.Clear();
- return path;
- }
- if (!this.Pairs.ContainsKey(current)) continue;
- HashSet<Edge2D> neighborEdges = this.Pairs[current];
- foreach (Edge2D neighborEdge in neighborEdges)
- {
- double dist = distance[current] + neighborEdge.Dist;
- var nextPoint = neighborEdge.GetNeighbor(current);
- switch (nextPoint)
- {
- case null:
- neighborEdge.Polyline.ColorIndex = 2;
- Flash.Update(neighborEdge.Polyline);
- Print(current);
- continue;
- default:
- if (!distance.ContainsKey(nextPoint.Value) || dist < distance[nextPoint.Value])
- {
- neighborEdge.Polyline.ColorIndex = 6;
- Flash.Update(neighborEdge.Polyline);
- distance[nextPoint.Value] = dist;
- previous[nextPoint.Value] = current;
- double heuristic = CalculateHeuristic2D(nextPoint.Value, end);
- double priority = dist + heuristic;
- queue.Enqueue(nextPoint.Value, priority);
- }
- else if (distance.ContainsKey(nextPoint.Value))
- {
- neighborEdge.Polyline.ColorIndex = 5;
- Flash.Update(neighborEdge.Polyline);
- }
- break;
- }
- }
- }
- Flash.Clear();
- return path;
- }
- private double CalculateHeuristic2D(Point2d current, Point2d end)
- {
- //return current.GetDistanceTo(end);
- return Math.Abs(current.X - end.X) + Math.Abs(current.Y - end.Y);
- }
- public class PriorityQueue2D<T>
- {
- private List<PriorityQueueElement<T>> elements = new List<PriorityQueueElement<T>>();
- private int counter = 0;
- public int Count => elements.Count;
- public void Enqueue(T item, double priority)
- {
- elements.Add(new PriorityQueueElement<T>(item, priority, counter));
- counter++;
- elements.Sort();
- }
- public T Dequeue()
- {
- var item = elements[0];
- elements.RemoveAt(0);
- return item.Value;
- }
- }
- public class PriorityQueueElement<T> : IComparable<PriorityQueueElement<T>>
- {
- public T Value { get; }
- public double Priority { get; }
- public int Counter { get; }
- public PriorityQueueElement(T value, double priority, int counter)
- {
- Value = value;
- Priority = priority;
- Counter = counter;
- }
- public int CompareTo(PriorityQueueElement<T> other)
- {
- int priorityComparison = Priority.CompareTo(other.Priority);
- if (priorityComparison != 0)
- return priorityComparison;
- else
- return Counter.CompareTo(other.Counter);
- }
- }
-
- }
- }
|
|