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 HousePathInfo housePathInfo = null; private bool moveable = false;//可移动的 private Line tempLine = null; private Polyline tempPolyline = null; // 当前图像 private System.Drawing.Image image; 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) { string json = this.housePathInfo.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); //} } /// /// 清理定位点 /// /// /// private void ClearPosition_Click(object sender, RoutedEventArgs e) { this.LocationPointLayer.Children.Clear(); this.housePathInfo.ClearLocationPosiltion(); } /// /// 鼠标按下 /// /// /// private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e) { //是否添加障碍物 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 != 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 != ZTPoint.Empty) { tempLine = CreateTempFindPathLineUI(fpPoint); this.HouseInfoLayer.Children.Add(tempLine); moveable = true; } } } /// /// 鼠标移动 /// /// /// private void SourceImage_MouseMove(object sender, MouseEventArgs e) { 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) { 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 != 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 != 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)) { //到起点,完成,画折线,向houseinfo里添加障碍物 Polygon polygon = CreateObstacleUI(); this.HouseInfoLayer.Children.Add(polygon); 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); } this.housePathInfo.AddObstacle(new ZTPolygon(obstaclePoints)); 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; } } } } /// /// 计算当前鼠标位置和颜色 /// /// /// /// /// 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; } /// /// 操作类型 /// public enum OperateActionD { Obstacle = 0,//障碍物 LocationPoint,//定位点 FindPathPoint,//寻路点 LoopLine,//循环线 FindPathLine,//寻路线 } #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(); } /// /// 创建定位点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() { // Polygon polygon = new Polygon(); 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; } /// /// 创建临时障碍物线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 default(ZTPoint); } #endregion #region Tools //private bool PointInRang(Point) #endregion } }