using Emgu.CV; using RichCreator.Utility; using RichCreator.Utility.PathFindings; using RichCreator.Utility.Structs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using ZTImage; namespace RichCreator.Editor.Tools { /// /// AStarTools.xaml 的交互逻辑 /// public partial class DijkstraTools : Window { public DijkstraTools() { InitializeComponent(); } // 寻路信息 private FindPathInfo info = null; private Border[] rects = new Border[0]; private bool isDown = false; //边线UI private Line edgeLine = null; //边线开始索引 private Int32 edgeStartIndex = 0; // 当前图像 private System.Drawing.Image image; /// /// 加载图片 /// /// /// private void OpenFromFile(object sender, RoutedEventArgs e) { string imagePath = string.Empty; Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); ofd.DefaultExt = ".jpg"; ofd.Filter = "image file|*.jpg;*.png;"; ofd.Multiselect = false; if (ofd.ShowDialog() == true) { imagePath = ofd.FileName; } else { return; } Mat source = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Color); this.image = source.Bitmap; SetImage(this.SourceImage); } /// /// 设置图像 /// /// /// private void SetImage(Image control) { BitmapImage t = ImageHelper.BitmapToImageSource(image); control.Source = t; if (control == this.SourceImage) { mainContainer.Width = image.Width; mainContainer.Height = image.Height; } } /// /// 生成方框 /// private void GenericRect(Int32 width,Int32 height,Int32 row,Int32 col) { ImageOverflowLayer.Children.Clear(); this.info = new FindPathInfo(width,height,row,col); Int32 count = this.info.RowCount * this.info.ColCount; this.rects = new Border[count]; for (int y = 0; y < this.info.RowCount; y++) { for (int x = 0; x < this.info.ColCount; x++) { //生成 GenericRect(y * this.info.ColCount + x, y, x, this.info.Width, this.info.Height); } } } /// /// 设为顶点 /// private void SetVertexUI(FindPathInfo.VertexInfo vertexInfo) { Int32 row, col; this.info.GetVertexRowColumn(out row, out col, vertexInfo.Index); Border border = this.rects[vertexInfo.Index]; TextBlock tb = border.Child as TextBlock; if (tb == null) { return; } this.info.AddVertex(vertexInfo); switch (vertexInfo.VertexType) { case 0: //普通顶点 border.Background = new SolidColorBrush(Colors.YellowGreen); tb.Text = vertexInfo.Index.ToString() + "\r\n(" + col.ToString() + "," + row.ToString() + ")"; break; case 1: //靠近点 border.Background = new SolidColorBrush(Colors.Green); tb.Text = vertexInfo.NearVertexIndex.ToString() + "\r\n(" + col.ToString() + "," + row.ToString() + ")"; break; case 2: //起点 border.Background = new SolidColorBrush(Colors.Yellow); tb.Text = vertexInfo.Index.ToString() + "(s)\r\n(" + col.ToString() + "," + row.ToString() + ")"; break; case 3: //终点 border.Background = new SolidColorBrush(Colors.Yellow); tb.Text = vertexInfo.Index.ToString() + "(e)\r\n(" + col.ToString() + "," + row.ToString() + ")"; break; } } /// /// 设置近顶点 /// /// private void SetNearVertex(Int32 index, Int32 nearIndex) { Int32 col = index % this.info.ColCount; Int32 row = index / this.info.ColCount; Border border = this.rects[index]; border.Background = new SolidColorBrush(Colors.Green); TextBlock tb = border.Child as TextBlock; if (tb == null) { return; } tb.Text = nearIndex.ToString() + "\r\n(" + col.ToString() + "," + row.ToString() + ")"; } /// /// 生成定位方框 /// /// private Border AddLocationPoint(Int32 x, Int32 y,Int32 number) { this.info.Positions.Add(new FindPathInfo.PointSerialize(x,y,number)); /* */ Border border = new Border(); border.Width = 60; border.Height = 40; border.BorderBrush = new SolidColorBrush(Colors.Red); border.BorderThickness = new Thickness(0); border.Opacity = 0.7f; border.IsHitTestVisible = false; StackPanel panel = new StackPanel(); panel.Orientation = System.Windows.Controls.Orientation.Vertical; panel.IsHitTestVisible = false; border.Child = panel; Ellipse ep = new Ellipse(); ep.Width = 5; ep.Height = 5; ep.Fill = new SolidColorBrush(Colors.Red); ep.StrokeThickness = 1; ep.HorizontalAlignment = HorizontalAlignment.Left; ep.IsHitTestVisible = false; panel.Children.Add(ep); TextBlock tb = new TextBlock(); tb.Foreground = new SolidColorBrush(Colors.Red); tb.Text = number.ToString() + "\r\n(" + x.ToString() + "," + y.ToString() + ")"; tb.HorizontalAlignment = HorizontalAlignment.Left; tb.IsHitTestVisible = false; panel.Children.Add(tb); Canvas.SetLeft(border, x); Canvas.SetTop(border, y); PositionOverflowLayer.Children.Add(border); return border; } /// /// 生成顶点方框 /// /// /// /// /// private void GenericRect(Int32 index,int row, int col, int width, int height) { // // // Border border = new Border(); border.Width = width; border.Height = height; border.BorderBrush= new SolidColorBrush(Colors.GreenYellow); border.BorderThickness=new Thickness (1); border.Opacity = 0.7f; border.IsHitTestVisible = false; TextBlock tb = new TextBlock(); tb.Text = index.ToString()+ "\r\n(" + col.ToString()+","+row.ToString()+")"; tb.HorizontalAlignment = HorizontalAlignment.Right; tb.VerticalAlignment = VerticalAlignment.Bottom; tb.FontSize = 7; tb.IsHitTestVisible = false; border.Child = tb; Canvas.SetLeft(border, col*width); Canvas.SetTop(border, row*height); ImageOverflowLayer.Children.Add(border); this.rects[index] = border; } /// /// 添加连接线 /// private void GenericEdge(Int32 index) { Int32 col = index % this.info.ColCount; Int32 row = index / this.info.ColCount; //连接顶点 Int32 x = col * this.info.Width + this.info.Width / 2; Int32 y = row * this.info.Height + this.info.Height / 2; edgeLine = new Line(); edgeLine.Stroke = new SolidColorBrush(Colors.Red); edgeLine.StrokeThickness = 1; edgeLine.X1 = x; edgeLine.Y1 = y; edgeStartIndex = index; this.ImageOverflowLayer.Children.Add(edgeLine); } /// /// 设置连接线 /// private void SetEdge(Int32 index) { Int32 row = index / this.info.ColCount; Int32 col = index % this.info.ColCount; //连接顶点 if (this.info.VertexCanAddEdge(index)) { this.info.Edges.Add(new FindPathInfo.EdgeInfo() { StartIndex = edgeStartIndex, EndIndex = index }); Int32 x = col * this.info.Width + this.info.Width / 2; Int32 y = row * this.info.Height + this.info.Height / 2; edgeLine.X2 = x; edgeLine.Y2 = y; } else { this.ImageOverflowLayer.Children.Remove(edgeLine); } } /// /// 添加顶点 /// /// /// private void GenericRect_Click(object sender, RoutedEventArgs e) { if (this.image == null) { MessageBox.Show("请选加载图片再生成方框"); return; } Int32 width = TypeConverter.StringToInt(this.rectWidth.Text, 0); Int32 height = TypeConverter.StringToInt(this.rectHeight.Text, 0); if (width <= 0 || height <= 0) { MessageBox.Show("宽高必须大于0"); return; } Int32 row = this.image.Height / height; if (this.image.Height % height != 0) { row++; } Int32 col = this.image.Width / width; if (this.image.Width % width!=0) { col++; } GenericRect(width, height, row, col); } /// /// 鼠标按下 /// /// /// private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e) { //是否添加障碍物 OperateActionD operateAction = (OperateActionD)(ClickOperate.SelectedIndex); VertexTypeD vertexType = (VertexTypeD)(tagVertexType.SelectedIndex); if (e.LeftButton == MouseButtonState.Released) { return; } Point point = GetPosition(e); Int32 row = (Int32)point.Y / this.info.Height; Int32 col = (Int32)point.X / this.info.Width; Int32 index = row * this.info.ColCount + col; Int32 number = TypeConverter.StringToInt(this.tagNumber.Text, 0); if (operateAction == OperateActionD.AddVertex) { FindPathInfo.VertexInfo vertex = new FindPathInfo.VertexInfo() { Index = index, VertexType = (Int32)vertexType, NearVertexIndex = number }; SetVertexUI(vertex); } else if (operateAction == OperateActionD.Link) { //添加顶点连接线 GenericEdge(index); edgeLine.X2 = point.X; edgeLine.Y2 = point.Y; } else if (operateAction == OperateActionD.LocationPoint) { //添加定位点 AddLocationPoint((Int32)point.X, (Int32)point.Y,number); } isDown = true; } /// /// 鼠标移动 /// /// /// private void SourceImage_MouseMove(object sender, MouseEventArgs e) { if (!isDown) { return; } OperateActionD operateAction = (OperateActionD)(ClickOperate.SelectedIndex); VertexTypeD vertexType = (VertexTypeD)(tagVertexType.SelectedIndex); Point point = GetPosition(e); Int32 row = (Int32)point.Y / this.info.Height; Int32 col = (Int32)point.X / this.info.Width; Int32 index = row * this.info.ColCount + col; Int32 number = ZTImage.TypeConverter.StringToInt(this.tagNumber.Text, 0); if (operateAction == OperateActionD.AddVertex) { FindPathInfo.VertexInfo vertex = new FindPathInfo.VertexInfo() { Index = index, VertexType = (Int32)vertexType, NearVertexIndex = number }; SetVertexUI(vertex); } else if (operateAction == OperateActionD.Link) { //连接顶点 edgeLine.X2 = point.X; edgeLine.Y2 = point.Y; } } /// /// 鼠标提起 /// /// /// private void SourceImage_MouseUp(object sender, MouseButtonEventArgs e) { if (!isDown) { return; } isDown = false; Point point = GetPosition(e); OperateActionD operateAction = (OperateActionD)(ClickOperate.SelectedIndex); VertexTypeD vertexType = (VertexTypeD)(tagVertexType.SelectedIndex); Int32 row = (Int32)point.Y / this.info.Height; Int32 col = (Int32)point.X / this.info.Width; Int32 index = row * this.info.ColCount + col; if (operateAction == OperateActionD.Link) { //连接顶点并添加到边列表里 SetEdge(index); } } /// /// 清空定位点 /// /// /// private void ClearVex_Click(object sender, RoutedEventArgs e) { this.PositionOverflowLayer.Children.Clear(); } /// /// 清空顶点 /// /// /// private void ClearRect_Click(object sender, RoutedEventArgs e) { ImageOverflowLayer.Children.Clear(); } /// /// 计算当前鼠标位置和颜色 /// /// /// /// /// private Point GetPosition(MouseEventArgs e ) { Point point = e.GetPosition(this.scrollViewer); Int32 x = (Int32)Math.Round(this.scrollViewer.HorizontalOffset + point.X); Int32 y = (Int32)Math.Round(this.scrollViewer.VerticalOffset + point.Y); return new Point(x, y); } /// /// 操作类型 /// public enum OperateActionD { AddVertex=0,//添加顶点 Link=1,//连接 LocationPoint=2//定位点 } /// /// 添加顶点类型 /// 顶点类型,0:普通顶点,1:依附顶点,2:起点,3:终点 /// public enum VertexTypeD { Common=0, Near=1, Start=2, End=3 } /// /// 复制JSON /// /// /// private void CopyJSON_Click(object sender, RoutedEventArgs e) { string json = this.info.ToJsonString(); Clipboard.SetDataObject(json, true); } /// /// 从JSON创建 /// /// /// private void CreateFromJSON_Click(object sender, RoutedEventArgs e) { SerializeInput input = new SerializeInput(); if (input.ShowDialog() != true) { return; } FindPathInfo pi = FindPathInfo.FromJsonString(input.ColorString); //生成网格 this.rectWidth.Text = pi.Width.ToString(); this.rectHeight.Text = pi.Height.ToString(); GenericRect(pi.Width, pi.Height, pi.RowCount, pi.ColCount); //生成顶点 for (int i = 0; i < pi.Vertexs.Count; i++) { SetVertexUI(pi.Vertexs[i]); } //生成连线 for (int i = 0; i < pi.Edges.Count; i++) { GenericEdge(pi.Edges[i].StartIndex); SetEdge(pi.Edges[i].EndIndex); } this.PositionOverflowLayer.Children.Clear(); //生成定位点 for (int i = 0; i < pi.Positions.Count; i++) { AddLocationPoint(pi.Positions[i].X, pi.Positions[i].Y, pi.Positions[i].Parameter); } } } }