using Emgu.CV;
|
using RichCreator.Utility;
|
using RichCreator.Utility.Maps;
|
using RichCreator.Utility.PathFinding;
|
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
|
{
|
/// <summary>
|
/// AStarTools.xaml 的交互逻辑
|
/// </summary>
|
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<ZTPoint> startEndFindPathPoint = new List<ZTPoint>();//测试寻路起点和终点
|
|
#region 事件
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
{
|
|
}
|
|
/// <summary>
|
/// 加载图片
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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();
|
}
|
|
/// <summary>
|
/// 复制JSON
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void CopyJSON_Click(object sender, RoutedEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
string json = this.housePathInfo.ToJsonString();
|
Clipboard.SetDataObject(json, true);
|
MessageBox.Show("copy success");
|
}
|
|
/// <summary>
|
/// 从JSON创建
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void CreateFromJSON_Click(object sender, RoutedEventArgs e)
|
{
|
if (!isinit)
|
{
|
MessageBox.Show("请先加载图片");
|
return;
|
}
|
|
SerializeInput input = new SerializeInput();
|
if (input.ShowDialog() != true)
|
{
|
return;
|
}
|
|
var info = HousePathInfo.FromJsonString(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.FindPathLines.Count; i++)
|
{
|
Line fpline = CreateFindPathLineUI(info.FindPathLines[i]);
|
this.HouseInfoLayer.Children.Add(fpline);
|
}
|
|
//加载巡逻点
|
if (!info.LoopPoint.Equals(ZTPoint.Empty))
|
{
|
Canvas llline = CreateLoopPointUI(info.LoopPoint);
|
this.HouseInfoLayer.Children.Add(llline);
|
}
|
|
|
//进门点
|
for (int i = 0; i < info.NextGates.Count; i++)
|
{
|
Canvas ng = CreateNextGateUI(info.NextGates[i]);
|
this.HouseInfoLayer.Children.Add(ng);
|
}
|
|
|
//加载导引区域
|
for (int i = 0; i < info.PathGuides.Count; i++)
|
{
|
Polygon pg = CreatePathGuideUI(info.PathGuides[i]);
|
this.PathGuideShapeLayer.Children.Add(pg);
|
}
|
|
|
|
this.housePathInfo = info;
|
}
|
|
/// <summary>
|
/// 生成定位图片
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void CreateLocationPicture(object sender, RoutedEventArgs e)
|
{
|
|
string dir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "numbers");
|
if (!System.IO.Directory.Exists(dir))
|
{
|
System.IO.Directory.CreateDirectory(dir);
|
}
|
|
for (Int32 i = 0; i <= 255; i++)
|
{
|
byte number = (byte)i;
|
System.Drawing.Bitmap image = new System.Drawing.Bitmap(12, 10);
|
//1
|
SetImagePixel(0, 0, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(2, 0, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(5, 0, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(7, 0, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(10, 0, 2, 2, image, System.Drawing.Color.White);
|
|
//2
|
SetImagePixel(0, 2, 2, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(10, 2, 2, 2, image, System.Drawing.Color.Black);
|
|
//3
|
SetImagePixel(0, 4, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(2, 4, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(5, 4, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(7, 4, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(10, 4, 2, 2, image, System.Drawing.Color.White);
|
|
//4
|
SetImagePixel(0, 6, 2, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(10, 6, 2, 2, image, System.Drawing.Color.Black);
|
|
//5
|
SetImagePixel(0, 8, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(2, 8, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(5, 8, 2, 2, image, System.Drawing.Color.White);
|
SetImagePixel(7, 8, 3, 2, image, System.Drawing.Color.Black);
|
SetImagePixel(10, 8, 2, 2, image, System.Drawing.Color.White);
|
Int32 x = 0, y = 0;
|
for (int bit = 0; bit <= 7; bit++)
|
{
|
GetBitCoordinate(out x, out y, bit);
|
if (HasValueInBit(number, bit))
|
{
|
SetImagePixel(x, y, 2, 2, image, System.Drawing.Color.White);
|
}
|
else
|
{
|
SetImagePixel(x, y, 2, 2, image, System.Drawing.Color.Black);
|
}
|
|
}
|
|
|
|
string saveDir = System.IO.Path.Combine(dir, number.ToString() + ".png");
|
image.Save(saveDir, System.Drawing.Imaging.ImageFormat.Png);
|
}
|
MessageBox.Show("数字文件生成成功,生成至程序目录:numbers目录下");
|
|
}
|
|
/// <summary>
|
/// 设置像素
|
/// </summary>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="width"></param>
|
/// <param name="height"></param>
|
/// <param name="image"></param>
|
/// <param name="color"></param>
|
private void SetImagePixel(Int32 x, Int32 y, Int32 width, Int32 height, System.Drawing.Bitmap image, System.Drawing.Color color)
|
{
|
for (int w = 0; w < width; w++)
|
{
|
for (Int32 h = 0; h < height; h++)
|
{
|
image.SetPixel(x + w, y + h, color);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 得到指定位坐标
|
/// </summary>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="bitIndex"></param>
|
private void GetBitCoordinate(out Int32 x, out Int32 y, Int32 bitIndex)
|
{
|
x = 0;
|
y = 0;
|
switch (bitIndex)
|
{
|
case 0:
|
x = 8;
|
y = 6;
|
break;
|
case 1:
|
x = 6;
|
y = 6;
|
break;
|
case 2:
|
x = 4;
|
y = 6;
|
break;
|
case 3:
|
x = 2;
|
y = 6;
|
break;
|
case 4:
|
x = 8;
|
y = 2;
|
break;
|
case 5:
|
x = 6;
|
y = 2;
|
break;
|
case 6:
|
x = 4;
|
y = 2;
|
break;
|
case 7:
|
x = 2;
|
y = 2;
|
break;
|
}
|
}
|
|
/// <summary>
|
/// 得到数字指定位是否有值
|
/// </summary>
|
/// <param name="number"></param>
|
/// <param name="bit"></param>
|
/// <returns></returns>
|
private bool HasValueInBit(byte number, Int32 bit)
|
{
|
switch (bit)
|
{
|
case 0:
|
return (number & 0b00000001) != 0;
|
case 1:
|
return (number & 0b00000010) != 0;
|
case 2:
|
return (number & 0b00000100) != 0;
|
case 3:
|
return (number & 0b00001000) != 0;
|
case 4:
|
return (number & 0b00010000) != 0;
|
case 5:
|
return (number & 0b00100000) != 0;
|
case 6:
|
return (number & 0b01000000) != 0;
|
case 7:
|
return (number & 0b10000000) != 0;
|
}
|
return true;
|
}
|
|
|
|
/// <summary>
|
/// 清理定位点
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void ClearPosition_Click(object sender, RoutedEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
this.LocationPointLayer.Children.Clear();
|
this.housePathInfo.ClearLocationPosiltion();
|
}
|
|
|
|
/// <summary>
|
/// 清空寻路测试点的起点和终点
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void ClearStartEndPoint_Click(object sender, RoutedEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
this.StartEndPointLayer.Children.Clear();
|
this.startEndFindPathPoint.Clear();
|
}
|
|
|
/// <summary>
|
/// 测试寻路
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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];
|
|
HouseInfo house = new HouseInfo(this.housePathInfo);
|
List<ZTPoint> path = house.FindPath(ref start, ref end);
|
|
if (path == null || path.Count <= 0)
|
{
|
MessageBox.Show("不用寻路");
|
return;
|
}
|
else
|
{
|
//绘制路径
|
ZTPoint lastPoint = start;
|
for (int i = 0; i < path.Count; i++)
|
{
|
|
Line line = GetPathLineUI(lastPoint, path[i]);
|
this.StartEndPointLayer.Children.Add(line);
|
lastPoint = path[i];
|
}
|
}
|
}
|
|
|
/// <summary>
|
/// 鼠标按下
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void SourceImage_MouseDown(object sender, MouseButtonEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
//是否添加障碍物
|
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
|
Int32 numParameter = TypeConverter.StringToInt(this.tagParameter.Text, 0);
|
string strParameter = this.tagParameter.Text;
|
|
if (e.LeftButton == MouseButtonState.Released)
|
{
|
return;
|
}
|
Point point = GetPosition(e);
|
|
|
if (op == OperateActionD.LocationPoint)
|
{
|
//定位点
|
ParametersPoint lp = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), numParameter);
|
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.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.LoopPoint)
|
{
|
//循环点
|
if (!this.housePathInfo.LoopPoint.Equals(ZTPoint.Empty))
|
{
|
//删除原来的巡逻点
|
}
|
|
ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y);
|
this.housePathInfo.LoopPoint = sepoint;
|
Canvas lp = CreateLoopPointUI(sepoint);
|
this.HouseInfoLayer.Children.Add(lp);
|
}
|
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);
|
}
|
else if (op == OperateActionD.ReadCoordinate)
|
{
|
//读取坐标
|
ZTPoint sepoint = new ZTPoint((Int32)point.X, (Int32)point.Y);
|
this.tagParameter.Text = sepoint.X.ToString() + "," + sepoint.Y.ToString();
|
}
|
else if (op == OperateActionD.NextGate)
|
{
|
//下一关的门
|
if (numParameter < 0 || numParameter > 3)
|
{
|
MessageBox.Show("参数必须是:0:上1:右2:下3:左");
|
return;
|
}
|
ParametersPoint ng = new ParametersPoint(new ZTPoint((Int32)point.X, (Int32)point.Y), numParameter);
|
if (this.housePathInfo.AddNextGate(ng))
|
{
|
Canvas ngControl = CreateNextGateUI(ng);
|
this.HouseInfoLayer.Children.Add(ngControl);
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 鼠标移动
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void SourceImage_MouseMove(object sender, MouseEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
|
Point point = GetPosition(e);
|
if (op == OperateActionD.FindPathLine)
|
{
|
//寻路线
|
if (!moveable)
|
{
|
return;
|
}
|
tempLine.X2 = point.X;
|
tempLine.Y2 = point.Y;
|
}
|
else if (op == OperateActionD.Obstacle||op==OperateActionD.PathGuide)
|
{
|
//障碍物线
|
if (!moveable)
|
{
|
return;
|
}
|
tempLine.X2 = point.X;
|
tempLine.Y2 = point.Y;
|
}
|
}
|
|
/// <summary>
|
/// 鼠标提起
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void SourceImage_MouseUp(object sender, MouseButtonEventArgs e)
|
{
|
if (!isinit)
|
{
|
return;
|
}
|
OperateActionD op = (OperateActionD)(slOperate.SelectedIndex);
|
Point point = GetPosition(e);
|
|
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|| op == OperateActionD.PathGuide)
|
{
|
//绘制障碍物或路径指导
|
//判断是否起点
|
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 (IsComplete(point) && this.points.Count > 2)
|
{
|
//到起点,完成,向houseinfo里添加障碍物 ,画折线,
|
ZTPoint[] points = new ZTPoint[this.points.Count];
|
for (int i = 0; i < this.points.Count; i++)
|
{
|
points[i] = new ZTPoint((Int32)this.points[i].X, (Int32)this.points[i].Y);
|
}
|
|
ZTPolygon ztpolygon = new ZTPolygon(points);
|
if (op == OperateActionD.Obstacle)
|
{
|
//障碍物
|
this.housePathInfo.AddObstacle(ztpolygon);
|
Polygon obstacle = CreateObstacleUI(ztpolygon);
|
this.HouseInfoLayer.Children.Add(obstacle);
|
}
|
else if (op == OperateActionD.PathGuide)
|
{
|
//路径导引
|
string strParameter = this.tagParameter.Text;
|
string[] sp = strParameter.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
if (sp.Length == 2)
|
{
|
ZTPoint targetPoint = new ZTPoint(TypeConverter.StringToInt(sp[0],0), TypeConverter.StringToInt(sp[1], 0));
|
ZTTargetPolygon targetPolygon = new ZTTargetPolygon(ztpolygon, targetPoint);
|
|
this.housePathInfo.AddPathGuide(targetPolygon);
|
var pathGuide = CreatePathGuideUI(targetPolygon);
|
this.PathGuideShapeLayer.Children.Add(pathGuide);
|
}
|
}
|
|
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
|
|
/// <summary>
|
/// 设置图像
|
/// </summary>
|
/// <param name="control"></param>
|
/// <param name="image"></param>
|
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;
|
});
|
}
|
|
|
/// <summary>
|
/// 创建定位点UI
|
/// 外方内圆
|
/// </summary>
|
private Canvas CreateLocationPointUI(ParametersPoint point)
|
{
|
//<Canvas Canvas.Left="point.x" Canvas.Top="point.y">
|
// <Rectangle Canvas.Left="-10" Canvas.Top="-10" Width="20" Height="20" Stroke="Red" StrokeThickness="1" />
|
// <Ellipse Canvas.Left="-2" Canvas.Top="-2" Width="4" Height="4" Fill="Red" StrokeThickness="1" />
|
//</Canvas>
|
|
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;
|
}
|
|
/// <summary>
|
/// 创建寻路点UI
|
/// </summary>
|
private Canvas CreateFindPathPointUI(ZTPoint findPathPoint)
|
{
|
//<Canvas Canvas.Left="point.x" Canvas.Top="point.y">
|
// <Ellipse Canvas.Left="-10" Canvas.Top="-10" Width="20" Height="20" Stroke="Red" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
// <Rectangle Canvas.Left="-2" Canvas.Top="-2" Width="4" Height="4" Fill="Red" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
//</Canvas>
|
|
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;
|
}
|
|
/// <summary>
|
/// 寻路点右击
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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);
|
}
|
|
}
|
|
|
|
/// <summary>
|
/// 创建临时巡逻线UI
|
/// </summary>
|
/// <param name="linePoint"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
|
/// <summary>
|
/// 创建寻路线UI
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 寻路线右键
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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);
|
}
|
}
|
|
|
/// <summary>
|
/// 创建临时寻路线UI
|
/// </summary>
|
/// <param name="linePoint"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 创建临时障碍物UI
|
/// </summary>
|
/// <returns></returns>
|
private Polyline CreateTempObstacleUI(Point point)
|
{
|
//<!--<Polygon StrokeThickness="1" Stroke="Black" Opacity="0.5">
|
// <Polygon.Points>10,50 180,50 180,150 </Polygon.Points>
|
// </Polygon>-->
|
Polyline polyline = new Polyline();
|
polyline.StrokeThickness = 1;
|
polyline.Stroke = new SolidColorBrush(Colors.Black);
|
polyline.Opacity = 0.5f;
|
polyline.Points.Add(point);
|
return polyline;
|
}
|
|
|
/// <summary>
|
/// 创建障碍物UI
|
/// </summary>
|
/// <returns></returns>
|
private Polygon CreateObstacleUI(ZTPolygon ztpolygon)
|
{
|
//<!--<Polygon StrokeThickness="1" Stroke="Black" Opacity="0.5">
|
// <Polygon.Points>10,50 180,50 180,150 </Polygon.Points>
|
// </Polygon>-->
|
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 < ztpolygon.Points.Length; i++)
|
{
|
polygon.Points.Add(new Point(ztpolygon.Points[i].X, ztpolygon.Points[i].Y));
|
}
|
|
return polygon;
|
}
|
|
/// <summary>
|
/// 障碍物右键删除
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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);
|
}
|
}
|
|
|
|
/// <summary>
|
/// 创建障碍物UI
|
/// </summary>
|
/// <returns></returns>
|
private Polygon CreatePathGuideUI(ZTTargetPolygon ztpolygon)
|
{
|
Polygon polygon = new Polygon();
|
polygon.Tag = ztpolygon;
|
polygon.MouseRightButtonUp += PathGuide_MouseRightButtonUp;
|
polygon.MouseEnter += PathGuide_MouseEnter;
|
polygon.MouseLeave += PathGuide_MouseLeave;
|
polygon.StrokeThickness = 1;
|
polygon.Stroke = new SolidColorBrush(Colors.Yellow);
|
polygon.Fill = new SolidColorBrush(Colors.Yellow);
|
polygon.Opacity = 0.7f;
|
for (int i = 0; i < ztpolygon.Polygon.Points.Length; i++)
|
{
|
polygon.Points.Add(new Point(ztpolygon.Polygon.Points[i].X, ztpolygon.Polygon.Points[i].Y));
|
}
|
|
return polygon;
|
}
|
|
/// <summary>
|
/// 移出路径指导区域
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void PathGuide_MouseLeave(object sender, MouseEventArgs e)
|
{
|
this.PathGuideLayer.Children.Clear();
|
}
|
|
/// <summary>
|
/// 移入路径指导区域
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void PathGuide_MouseEnter(object sender, MouseEventArgs e)
|
{
|
Polygon c = sender as Polygon;
|
if (c == null)
|
{
|
return;
|
}
|
|
ZTTargetPolygon ztp = default(ZTTargetPolygon);
|
try
|
{
|
ztp = (ZTTargetPolygon)c.Tag;
|
}
|
catch
|
{
|
return;
|
}
|
this.PathGuideLayer.Children.Clear();
|
|
|
Canvas main = new Canvas();
|
main.MouseRightButtonUp += NextGate_MouseRightButtonUp;
|
Canvas.SetLeft(main, ztp.Target.X);
|
Canvas.SetTop(main, ztp.Target.Y);
|
|
Rectangle rect = new Rectangle();
|
Canvas.SetLeft(rect, -10);
|
Canvas.SetTop(rect, -10);
|
rect.Width = 20;
|
rect.Height = 20;
|
rect.Stroke = new SolidColorBrush(Colors.Blue);
|
rect.StrokeThickness = 1;
|
rect.Fill = new SolidColorBrush(Colors.Blue);
|
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 = ztp.Target.ToString();
|
tb.FontSize = 9;
|
main.Children.Add(tb);
|
|
this.PathGuideLayer.Children.Add(main);
|
}
|
|
/// <summary>
|
/// 障碍物右键删除
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void PathGuide_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
|
{
|
Polygon c = sender as Polygon;
|
if (c == null)
|
{
|
return;
|
}
|
|
ZTTargetPolygon ztp = default(ZTTargetPolygon);
|
try
|
{
|
ztp = (ZTTargetPolygon)c.Tag;
|
}
|
catch
|
{
|
return;
|
}
|
if (this.housePathInfo.RemovePathGuide(ztp))
|
{
|
this.PathGuideShapeLayer.Children.Remove(c);
|
}
|
}
|
|
/// <summary>
|
/// 创建临时障碍物线UI
|
/// </summary>
|
/// <param name="linePoint"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 获取当前位置点
|
/// </summary>
|
/// <param name="point"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
|
/// <summary>
|
/// 创建起始和终止寻路点
|
/// </summary>
|
/// <param name="point"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 创建路径线
|
/// </summary>
|
/// <param name="start"></param>
|
/// <param name="end"></param>
|
/// <returns></returns>
|
private Line GetPathLineUI(ZTPoint start, ZTPoint end)
|
{
|
Line edgeLine = new Line();
|
edgeLine.Stroke = new SolidColorBrush(Colors.Green);
|
edgeLine.StrokeThickness = 1;
|
edgeLine.X1 = start.X;
|
edgeLine.Y1 = start.Y;
|
|
edgeLine.X2 = end.X;
|
edgeLine.Y2 = end.Y;
|
|
|
return edgeLine;
|
}
|
|
/// <summary>
|
/// 创建进入下一关的门UI
|
/// 外方内圆
|
/// </summary>
|
private Canvas CreateNextGateUI(ParametersPoint point)
|
{
|
Canvas main = new Canvas();
|
main.Tag = point;
|
main.MouseRightButtonUp += NextGate_MouseRightButtonUp;
|
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.GreenYellow);
|
rect.StrokeThickness = 1;
|
rect.Fill = new SolidColorBrush(Colors.GreenYellow);
|
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;
|
}
|
|
private void NextGate_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
|
{
|
Canvas c = sender as Canvas;
|
if (c == null)
|
{
|
return;
|
}
|
|
ParametersPoint fp = default(ParametersPoint);
|
try
|
{
|
fp = (ParametersPoint)c.Tag;
|
}
|
catch
|
{
|
return;
|
}
|
if (this.housePathInfo.RemoveNextGate(fp))
|
{
|
this.HouseInfoLayer.Children.Remove(c);
|
}
|
|
}
|
|
/// <summary>
|
/// 创建循环点界面
|
/// </summary>
|
/// <param name="point"></param>
|
/// <returns></returns>
|
private Canvas CreateLoopPointUI(ZTPoint point)
|
{
|
Canvas main = new Canvas();
|
main.Tag = point;
|
main.MouseRightButtonUp += LoopPoint_MouseRightButtonUp;
|
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.OrangeRed);
|
rect.StrokeThickness = 1;
|
rect.Fill = new SolidColorBrush(Colors.OrangeRed);
|
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;
|
}
|
|
|
private void LoopPoint_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;
|
}
|
this.housePathInfo.LoopPoint = ZTPoint.Empty;
|
this.HouseInfoLayer.Children.Remove(c);
|
}
|
#endregion
|
|
#region Tools
|
|
/// <summary>
|
/// 计算当前鼠标位置和颜色
|
/// </summary>
|
/// <param name="e"></param>
|
/// <param name="point"></param>
|
/// <param name="color"></param>
|
/// <returns></returns>
|
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<Point> points = new List<Point>();
|
/// <summary>
|
/// 是否第一个点
|
/// </summary>
|
/// <param name="point"></param>
|
/// <returns></returns>
|
private bool IsComplete(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;
|
}
|
|
/// <summary>
|
/// 是否最后一个点
|
/// </summary>
|
/// <param name="point"></param>
|
/// <returns></returns>
|
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
|
|
/// <summary>
|
/// 操作类型
|
/// </summary>
|
public enum OperateActionD
|
{
|
Obstacle = 0,//障碍物
|
LocationPoint,//定位点
|
FindPathPoint,//寻路点
|
FindPathLine,//寻路线
|
LoopPoint,//循环点
|
NextGate,//入门点
|
PathGuide,//路径引导
|
ReadCoordinate,//读取坐标
|
StartEndPoint,//测试起终点
|
}
|
|
|
}
|
}
|