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 bool isinit = false;//是否加载图片 private HousePathInfo housePathInfo = null;//房间信息 private bool moveable = false;//可移动的 private Line tempLine = null;//临时线 private Polyline tempPolyline = null;//临时障碍物 private System.Drawing.Image image = null;// 当前图像 private List startEndFindPathPoint = new List();//测试寻路起点和终点 #region 事件 private void Window_Loaded(object sender, RoutedEventArgs e) { } /// /// 加载图片 /// /// /// private void OpenFromFile_Click(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(); } /// /// 复制JSON /// /// /// private void CopyJSON_Click(object sender, RoutedEventArgs e) { if (!isinit) { return; } string json = this.housePathInfo.ToJsonString(); Clipboard.SetDataObject(json, true); MessageBox.Show("copy success"); } /// /// 从JSON创建 /// /// /// private void CreateFromJSON_Click(object sender, RoutedEventArgs e) { if (!isinit) { MessageBox.Show("请先加载图片"); return; } SerializeInput input = new SerializeInput(); if (input.ShowDialog() != true) { return; } var info = ZTImage.Json.JsonParser.ToObject(input.ColorString); if (info == null) { return; } //依次加载,障碍物,定位点,寻路点,巡逻线,寻路线 //加载障碍物 for (int i = 0; i < info.Obstacles.Count; i++) { Polygon polygon=CreateObstacleUI(info.Obstacles[i]); this.HouseInfoLayer.Children.Add(polygon); } //加载定位点 for (int i = 0; i < info.LocationPoints.Count; i++) { Canvas lp = CreateLocationPointUI(info.LocationPoints[i]); this.HouseInfoLayer.Children.Add(lp); } //加载寻路点 for (int i = 0; i < info.FindPathPoints.Count; i++) { Canvas fp = CreateFindPathPointUI(info.FindPathPoints[i]); this.HouseInfoLayer.Children.Add(fp); } //加载巡逻线 for (int i = 0; i < info.LoopLines.Count; i++) { Line llline = CreateLoopLineUI(info.LoopLines[i]); this.HouseInfoLayer.Children.Add(llline); } //加载寻路线 for (int i = 0; i < info.FindPathLines.Count; i++) { Line fpline = CreateFindPathLineUI(info.FindPathLines[i]); this.HouseInfoLayer.Children.Add(fpline); } this.housePathInfo = info; } /// /// 清理定位点 /// /// /// private void ClearPosition_Click(object sender, RoutedEventArgs e) { if (!isinit) { return; } this.LocationPointLayer.Children.Clear(); this.housePathInfo.ClearLocationPosiltion(); } /// /// 清空寻路测试点的起点和终点 /// /// /// private void ClearStartEndPoint_Click(object sender, RoutedEventArgs e) { if (!isinit) { return; } this.StartEndPointLayer.Children.Clear(); this.startEndFindPathPoint.Clear(); } /// /// 测试寻路 /// /// /// private void TestFindPath_Click(object sender, RoutedEventArgs e) { if (this.startEndFindPathPoint.Count < 2) { MessageBox.Show("请选择测试的起点和终点"); } ZTPoint start = this.startEndFindPathPoint[0]; ZTPoint end = this.startEndFindPathPoint[1]; List path=this.housePathInfo.FindPath(start, end); //todo:绘制路径 } /// /// 鼠标按下 /// /// /// private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e) { if (!isinit) { return; } //是否添加障碍物 OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); Int32 number = TypeConverter.StringToInt(this.tagNumber.Text, 0); if (e.LeftButton == MouseButtonState.Released) { return; } Point point = GetPosition(e); if (op == OperateActionD.Obstacle) { //障碍物 } else if (op == OperateActionD.LocationPoint) { //定位点 ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), number); if (this.housePathInfo.AddLocationPosition(lp)) { Canvas lpControl = CreateLocationPointUI(lp); this.LocationPointLayer.Children.Add(lpControl); } } else if (op == OperateActionD.FindPathPoint) { //寻路点 ZTPoint fp = new ZTPoint((Int32)point.X, (Int32)point.Y); if (this.housePathInfo.AddFindPathPoint(fp)) { Canvas fpControl = CreateFindPathPointUI(fp); this.HouseInfoLayer.Children.Add(fpControl); } } else if (op == OperateActionD.LoopLine) { //循环线 ZTPoint llPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); if (!llPoint.Equals(ZTPoint.Empty)) { tempLine = CreateTempLoopLineUI(llPoint); this.HouseInfoLayer.Children.Add(tempLine); moveable = true; } } else if (op == OperateActionD.FindPathLine) { //寻路线 ZTPoint fpPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); if (!fpPoint.Equals(ZTPoint.Empty)) { tempLine = CreateTempFindPathLineUI(fpPoint); this.HouseInfoLayer.Children.Add(tempLine); moveable = true; } } else if (op == OperateActionD.StartEndPoint) { //画寻路起始和终点 ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y); Canvas lseControl = CreateStartEndPointUI(sepoint); this.StartEndPointLayer.Children.Add(lseControl); this.startEndFindPathPoint.Add(sepoint); } } /// /// 鼠标移动 /// /// /// private void SourceImage_MouseMove(object sender, MouseEventArgs e) { if (!isinit) { return; } OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); Point point = GetPosition(e); if (op == OperateActionD.LoopLine) { //巡逻线 if (!moveable) { return; } tempLine.X2 = point.X; tempLine.Y2 = point.Y; } else if (op == OperateActionD.FindPathLine) { //寻路线 if (!moveable) { return; } tempLine.X2 = point.X; tempLine.Y2 = point.Y; } else if (op == OperateActionD.Obstacle) { //障碍物线 if (!moveable) { return; } tempLine.X2 = point.X; tempLine.Y2 = point.Y; } } /// /// 鼠标提起 /// /// /// private void SourceImage_MouseUp(object sender, MouseButtonEventArgs e) { if (!isinit) { return; } OperateActionD op = (OperateActionD)(slOperate.SelectedIndex); Point point = GetPosition(e); if (op == OperateActionD.LoopLine) { //巡逻线 if (!moveable) { return; } moveable = false; if (tempLine == null) { return; } ZTPoint startPoint = (ZTPoint)tempLine.Tag; ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); if (!centerPoint.Equals(ZTPoint.Empty)) { ZTLinePoint ll = new ZTLinePoint(startPoint, centerPoint); if (this.housePathInfo.AddLoopLine(ll)) { Line llline = CreateLoopLineUI(ll); this.HouseInfoLayer.Children.Add(llline); } } this.HouseInfoLayer.Children.Remove(tempLine); tempLine = null; } else if (op == OperateActionD.FindPathLine) { //寻路线 if (!moveable) { return; } moveable = false; if (tempLine == null) { return; } ZTPoint startPoint = (ZTPoint)tempLine.Tag; ZTPoint centerPoint = GetFindPathPoint(new ZTPoint((Int32)point.X, (Int32)point.Y)); if (!centerPoint.Equals(ZTPoint.Empty)) { ZTLinePoint fp = new ZTLinePoint(startPoint, centerPoint); if (this.housePathInfo.AddFindPathLine(fp)) { Line fpline = CreateFindPathLineUI(fp); this.HouseInfoLayer.Children.Add(fpline); } } this.HouseInfoLayer.Children.Remove(tempLine); tempLine = null; } else if (op == OperateActionD.Obstacle) { //绘制障碍物 //判断是否起点 if (tempPolyline == null) { //首次画 this.points.Add(point); this.tempPolyline = CreateTempObstacleUI(point); this.tempLine = CreateObstacleLineUI(new ZTPoint((Int32)point.X, (Int32)point.Y)); moveable = true; this.HouseInfoLayer.Children.Add(this.tempPolyline); this.HouseInfoLayer.Children.Add(this.tempLine); } else { if (IsLastPoint(point)) { //判断是否跟最后一个点重合,如果重合则不处理 //判断是否只有两个点,如果是则不处理 return; } if (IsFirstPoint(point) && this.points.Count > 2) { //到起点,完成,向houseinfo里添加障碍物 ,画折线, ZTPoint[] obstaclePoints = new ZTPoint[this.points.Count]; for (int i = 0; i < this.points.Count; i++) { obstaclePoints[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y); } ZTPolygon ztpolygon = new ZTPolygon(obstaclePoints); this.housePathInfo.AddObstacle(ztpolygon); Polygon polygon = CreateObstacleUI(ztpolygon); this.HouseInfoLayer.Children.Add(polygon); this.HouseInfoLayer.Children.Remove(tempPolyline); tempPolyline = null; this.HouseInfoLayer.Children.Remove(tempLine); tempLine = null; this.points.Clear(); moveable = false; } else { //向points里添加障碍点,画折线,更新tempLine, this.points.Add(point); //画折线 this.tempPolyline.Points.Add(point); //更新tempLine tempLine.X1 = point.X; tempLine.Y1 = point.Y; tempLine.X2 = point.X; tempLine.Y2 = point.Y; } } } } #endregion #region createUI /// /// 设置图像 /// /// /// private void SetImage() { BitmapImage t = ImageHelper.BitmapToImageSource(image); this.SourceImage.Source = t; mainContainer.Width = image.Width; mainContainer.Height = image.Height; this.housePathInfo = new HousePathInfo(image.Width, image.Height); System.Threading.ThreadPool.QueueUserWorkItem((obj) => { System.Threading.Thread.Sleep(1000); isinit = true; }); } /// /// 创建定位点UI /// 外方内圆 /// private Canvas CreateLocationPointUI(ParametersPoint point) { // // // // Canvas main = new Canvas(); main.Tag = point; Canvas.SetLeft(main, point.Point.X); Canvas.SetTop(main, point.Point.Y); Rectangle rect = new Rectangle(); Canvas.SetLeft(rect, -10); Canvas.SetTop(rect, -10); rect.Width = 20; rect.Height = 20; rect.Stroke = new SolidColorBrush(Colors.Red); rect.StrokeThickness = 1; rect.Fill = new SolidColorBrush(Colors.Red); rect.Opacity = 0.5f; main.Children.Add(rect); Ellipse elli = new Ellipse(); Canvas.SetLeft(elli, -2); Canvas.SetTop(elli, -2); elli.Width = 4; elli.Height = 4; elli.Stroke = new SolidColorBrush(Colors.Black); elli.StrokeThickness = 1; elli.Fill = new SolidColorBrush(Colors.Black); main.Children.Add(elli); TextBlock tb = new TextBlock(); tb.Text = point.Parameter.ToString(); tb.FontSize = 9; main.Children.Add(tb); return main; } /// /// 创建寻路点UI /// private Canvas CreateFindPathPointUI(ZTPoint findPathPoint) { // // // // Canvas main = new Canvas(); main.Tag = findPathPoint; main.MouseRightButtonUp += FindPathPoint_MouseRightButtonUp; Canvas.SetLeft(main, findPathPoint.X); Canvas.SetTop(main, findPathPoint.Y); Ellipse elli = new Ellipse(); Canvas.SetLeft(elli, -10); Canvas.SetTop(elli, -10); elli.Width = 20; elli.Height = 20; elli.Stroke = new SolidColorBrush(Colors.Red); elli.StrokeThickness = 1; elli.Fill = new SolidColorBrush(Colors.Red); elli.Opacity = 0.5f; main.Children.Add(elli); Rectangle rect = new Rectangle(); Canvas.SetLeft(rect, -2); Canvas.SetTop(rect, -2); rect.Width = 4; rect.Height = 4; rect.Stroke = new SolidColorBrush(Colors.Black); rect.StrokeThickness = 1; rect.Fill = new SolidColorBrush(Colors.Black); rect.StrokeThickness = 1; main.Children.Add(rect); return main; } /// /// 寻路点右击 /// /// /// private void FindPathPoint_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { Canvas c = sender as Canvas; if (c == null) { return; } ZTPoint fp = default(ZTPoint); try { fp = (ZTPoint)c.Tag; } catch { return; } if (this.housePathInfo.RemoveFindPathPoint(fp)) { this.HouseInfoLayer.Children.Remove(c); } } /// /// 创建巡逻线UI /// private Line CreateLoopLineUI(ZTLinePoint linePoint) { Line edgeLine = new Line(); edgeLine.Tag = linePoint; edgeLine.MouseRightButtonUp += LoopLine_MouseRightButtonUp; edgeLine.Stroke = new SolidColorBrush(Colors.Red); edgeLine.StrokeThickness = 6; edgeLine.X1 = linePoint.X1; edgeLine.Y1 = linePoint.Y1; edgeLine.X2 = linePoint.X2; edgeLine.Y2 = linePoint.Y2; edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 }; edgeLine.StrokeDashCap = PenLineCap.Triangle; edgeLine.StrokeEndLineCap = PenLineCap.Square; edgeLine.StrokeStartLineCap = PenLineCap.Round; return edgeLine; } /// /// 巡逻线右击 /// /// /// private void LoopLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { Line c = sender as Line; if (c == null) { return; } ZTLinePoint fp = default(ZTLinePoint); try { fp = (ZTLinePoint)c.Tag; } catch { return; } if (this.housePathInfo.RemoveLoopLine(fp)) { this.HouseInfoLayer.Children.Remove(c); } } /// /// 创建临时巡逻线UI /// /// /// private Line CreateTempLoopLineUI(ZTPoint point) { Line edgeLine = new Line(); edgeLine.Tag = point; edgeLine.Stroke = new SolidColorBrush(Colors.Red); edgeLine.StrokeThickness = 3; edgeLine.X1 = point.X; edgeLine.Y1 = point.Y; edgeLine.X2 = point.X; edgeLine.Y2 = point.Y; edgeLine.StrokeDashArray = new DoubleCollection() { 2, 3 }; edgeLine.StrokeDashCap = PenLineCap.Triangle; edgeLine.StrokeEndLineCap = PenLineCap.Square; edgeLine.StrokeStartLineCap = PenLineCap.Round; return edgeLine; } /// /// 创建寻路线UI /// private Line CreateFindPathLineUI(ZTLinePoint linePoint) { Line edgeLine = new Line(); edgeLine.Tag = linePoint; edgeLine.MouseRightButtonUp += FindPathLine_MouseRightButtonUp; ; edgeLine.Stroke = new SolidColorBrush(Colors.Red); edgeLine.StrokeThickness = 3; edgeLine.X1 = linePoint.X1; edgeLine.Y1 = linePoint.Y1; edgeLine.X2 = linePoint.X2; edgeLine.Y2 = linePoint.Y2; return edgeLine; } /// /// 寻路线右键 /// /// /// private void FindPathLine_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { Line c = sender as Line; if (c == null) { return; } ZTLinePoint fp = default(ZTLinePoint); try { fp = (ZTLinePoint)c.Tag; } catch { return; } if (this.housePathInfo.RemoveFindPathLine(fp)) { this.HouseInfoLayer.Children.Remove(c); } } /// /// 创建临时寻路线UI /// /// /// private Line CreateTempFindPathLineUI(ZTPoint point) { Line edgeLine = new Line(); edgeLine.Tag = point; edgeLine.Stroke = new SolidColorBrush(Colors.Red); edgeLine.StrokeThickness = 3; edgeLine.X1 = point.X; edgeLine.Y1 = point.Y; edgeLine.X2 = point.X; edgeLine.Y2 = point.Y; return edgeLine; } /// /// 创建临时障碍物UI /// /// private Polyline CreateTempObstacleUI(Point point) { // Polyline polyline = new Polyline(); polyline.StrokeThickness = 1; polyline.Stroke = new SolidColorBrush(Colors.Black); polyline.Opacity = 0.5f; polyline.Points.Add(point); return polyline; } /// /// 创建障碍物UI /// /// private Polygon CreateObstacleUI(ZTPolygon ztpolygon) { // Polygon polygon = new Polygon(); polygon.Tag = ztpolygon; polygon.MouseRightButtonUp += Polygon_MouseRightButtonUp; polygon.StrokeThickness = 1; polygon.Stroke = new SolidColorBrush(Colors.Black); polygon.Fill = new SolidColorBrush(Colors.Black); polygon.Opacity = 0.7f; for (int i = 0; i < this.points.Count; i++) { polygon.Points.Add(this.points[i]); } return polygon; } /// /// 障碍物右键删除 /// /// /// private void Polygon_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { Polygon c = sender as Polygon; if (c == null) { return; } ZTPolygon ztp = default(ZTPolygon); try { ztp = (ZTPolygon)c.Tag; } catch { return; } if (this.housePathInfo.RemoveObstacle(ztp)) { this.HouseInfoLayer.Children.Remove(c); } } /// /// 创建临时障碍物线UI /// /// /// private Line CreateObstacleLineUI(ZTPoint point) { Line edgeLine = new Line(); edgeLine.Tag = point; edgeLine.Stroke = new SolidColorBrush(Colors.Black); edgeLine.StrokeThickness = 1; edgeLine.X1 = point.X; edgeLine.Y1 = point.Y; edgeLine.X2 = point.X; edgeLine.Y2 = point.Y; return edgeLine; } /// /// 获取当前位置点 /// /// /// private ZTPoint GetFindPathPoint(ZTPoint point) { ZTPoint temp = ZTPoint.Empty; for (int i = 0; i < this.housePathInfo.FindPathPoints.Count; i++) { temp = this.housePathInfo.FindPathPoints[i]; if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) { return temp; } } return ZTPoint.Empty; } /// /// 创建起始和终止寻路点 /// /// /// private Canvas CreateStartEndPointUI(ZTPoint point) { Canvas main = new Canvas(); main.Tag = point; Canvas.SetLeft(main, point.X); Canvas.SetTop(main, point.Y); Rectangle rect = new Rectangle(); Canvas.SetLeft(rect, -10); Canvas.SetTop(rect, -10); rect.Width = 20; rect.Height = 20; rect.Stroke = new SolidColorBrush(Colors.Green); rect.StrokeThickness = 1; rect.Fill = new SolidColorBrush(Colors.Green); rect.Opacity = 0.5f; main.Children.Add(rect); Ellipse elli = new Ellipse(); Canvas.SetLeft(elli, -2); Canvas.SetTop(elli, -2); elli.Width = 4; elli.Height = 4; elli.Stroke = new SolidColorBrush(Colors.Black); elli.StrokeThickness = 1; elli.Fill = new SolidColorBrush(Colors.Black); main.Children.Add(elli); return main; } #endregion #region Tools /// /// 计算当前鼠标位置和颜色 /// /// /// /// /// 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); } private List points = new List(); /// /// 是否第一个点 /// /// /// private bool IsFirstPoint(Point point) { Point temp = this.points[0]; if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) { return true; } return false; } /// /// 是否最后一个点 /// /// /// private bool IsLastPoint(Point point) { Point temp = this.points[this.points.Count - 1]; if (Math.Abs(temp.X - point.X) <= 10 && Math.Abs(temp.Y - point.Y) <= 10) { return true; } return false; } #endregion /// /// 操作类型 /// public enum OperateActionD { Obstacle = 0,//障碍物 LocationPoint,//定位点 FindPathPoint,//寻路点 LoopLine,//循环线 FindPathLine,//寻路线 StartEndPoint,//测试起终点 } } }