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 MapEditor : Window
{
public MapEditor()
{
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 Polygon myPolygon = null;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Polygon p = new Polygon();
p.Stroke = Brushes.Black;
p.Fill = Brushes.LightBlue;
p.StrokeThickness = 5;
p.HorizontalAlignment = HorizontalAlignment.Left;
p.VerticalAlignment = VerticalAlignment.Center;
p.Points = new System.Windows.Media.PointCollection() { new Point(10, 10), new Point(100, 100), new Point(200, 200) };
this.mainContainer.Children.Add(p);
}
///
/// 设置图像
///
///
///
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);
}
}
}
}