487 lines
18 KiB
C#
487 lines
18 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections;
|
|
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 FlightRouteV2;
|
|
using FlieOperate;
|
|
using static FlieOperate.FcgmJsonModel.Tasks.SingleCopterInfos;
|
|
using FlyCube.Models;
|
|
using ControlLibrary;
|
|
using WpfAnimatedGif;//播放GIF
|
|
using System.Security.Cryptography;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Windows.Media.Animation;
|
|
|
|
namespace FlyCube
|
|
{
|
|
public partial class MainWindow : Window
|
|
{
|
|
private TextBox LOG;
|
|
//绕行线程取消
|
|
CancellationTokenSource cts = new CancellationTokenSource();
|
|
/// <summary>
|
|
/// 入口函数
|
|
/// </summary>
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
//创建一个 主画布对象
|
|
TopCanvas = new MainCanvas(this.LayerPlane);
|
|
|
|
//List<Vector3[]> abVecs = FileBase.TxtToPos("C:/Users/szdot/Desktop/1.txt", out string[] fightNames);//从txt文件里面读取航点 信息
|
|
//Vector3[] aVecs = abVecs[0].ToArray();
|
|
//Vector3[] bVecs = abVecs[1].ToArray();
|
|
//Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
|
//List<List<Vector3>> listVecs = FlyVecFun.CollisionLayer(aVecs, new_bVecs, StrPrintAsync);
|
|
|
|
//string txta = "";
|
|
//string txtb = "";
|
|
//string txtd = "";
|
|
//for (int i = 0; i < bVecs.Length; i++)
|
|
//{
|
|
// txta += i + " 0" + " " + listVecs[0][i].X + " " + listVecs[0][i].Y + " " + listVecs[0][i].Z + "\r\n";
|
|
// txtb += i + " 0" + " " + listVecs[1][i].X + " " + listVecs[1][i].Y + " " + listVecs[1][i].Z + "\r\n";
|
|
// txtd += i + " 0" + " " + new_bVecs[i].X + " " + new_bVecs[i].Y + " " + new_bVecs[i].Z + "\r\n";
|
|
//}
|
|
//string patha = "C:/Users/szdot/Desktop/a.txt";
|
|
//string pathb = "C:/Users/szdot/Desktop/b.txt";
|
|
//string pathd = "C:/Users/szdot/Desktop/d.txt";
|
|
//if (File.Exists(patha))
|
|
//{
|
|
// File.Delete(patha);
|
|
//}
|
|
//SaveFile(patha, txta);
|
|
//if (File.Exists(pathb))
|
|
//{
|
|
// File.Delete(pathb);
|
|
//}
|
|
//SaveFile(pathb, txtb);
|
|
//if (File.Exists(pathd))
|
|
//{
|
|
// File.Delete(pathd);
|
|
//}
|
|
//SaveFile(pathd, txtd);
|
|
|
|
}
|
|
private async void CollisionLayer_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
//资源管理器 获取航点文件路径
|
|
FileBase.FileClass = new string[] { "航点文件" };
|
|
FileBase.Pascal = new string[] { "*.txt" };
|
|
string FliePath = FileBase.OpenExplorer("航点文件导入", out bool isSelect);
|
|
if (isSelect)
|
|
{
|
|
List<Vector3[]> abVecs = FileBase.TxtToPos(FliePath, out string[] fightNames);//从txt文件里面读取航点 信息
|
|
Vector3[] aVecs = abVecs[0].ToArray();
|
|
Vector3[] bVecs = abVecs[1].ToArray();
|
|
Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
|
Task<List<List<Vector3>>> reTask = Task.Run(() => FlyVecFun.CollisionLayer(aVecs, new_bVecs, StrPrintAsync));
|
|
List<List<Vector3>> re = await reTask;
|
|
|
|
string txta = "";
|
|
string txtb = "";
|
|
string txtd = "";
|
|
|
|
for (int i = 0; i < abVecs[0].Length; i++)
|
|
{
|
|
if (re.Count > 0)
|
|
{
|
|
txta += i + " 0" + " " + re[0][i].X + " " + re[0][i].Y + " " + re[0][i].Z + "\r\n";
|
|
}
|
|
if (re.Count > 1)
|
|
{
|
|
txtb += i + " 0" + " " + re[1][i].X + " " + re[1][i].Y + " " + re[1][i].Z + "\r\n";
|
|
}
|
|
txtd += i + " 0" + " " + new_bVecs[i].X + " " + new_bVecs[i].Y + " " + new_bVecs[i].Z + "\r\n";
|
|
|
|
}
|
|
if (re.Count > 0)
|
|
{
|
|
string path = "C:/Users/szdot/Desktop/a.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
SaveFile(path, txta);
|
|
}
|
|
if (re.Count > 1)
|
|
{
|
|
string path = "C:/Users/szdot/Desktop/b.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
SaveFile(path, txtb);
|
|
}
|
|
|
|
string pathd = "C:/Users/szdot/Desktop/d.txt";
|
|
if (File.Exists(pathd))
|
|
{
|
|
File.Delete(pathd);
|
|
}
|
|
SaveFile(pathd, txtd);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 3D绕行
|
|
/// </summary>
|
|
private async void ByPass_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
//资源管理器 获取航点文件路径
|
|
FileBase.FileClass = new string[] { "航点文件" };
|
|
FileBase.Pascal = new string[] { "*.txt" };
|
|
string FliePath = FileBase.OpenExplorer("航点文件导入", out bool isSelect);
|
|
if (isSelect)
|
|
{
|
|
List<Vector3[]> abVecs = FileBase.TxtToPos(FliePath, out string[] fightNames);//从txt文件里面读取航点 信息
|
|
Vector3[] aVecs = abVecs[0].ToArray();
|
|
Vector3[] bVecs = abVecs[1].ToArray();
|
|
Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
|
//Vector3[] new_aVecs = FlyVecFun.NormalPull(aVecs, bVecs, StrPrintAsync);//拉散图案
|
|
bool isPass;
|
|
Task<List<List<Vector3>>> reTask = Task.Run(() => FlyVecFun.ABypassB(aVecs, bVecs, StrPrintAsync, GetVal, cts.Token, out isPass));
|
|
List<List<Vector3>> re = await reTask;
|
|
|
|
string txta = "";
|
|
string txtb = "";
|
|
string txtc = "";
|
|
string txtd = "";
|
|
|
|
for (int i = 0; i < abVecs[0].Length; i++)
|
|
{
|
|
if (re.Count > 0)
|
|
{
|
|
txta += i + " 0" + " " + re[0][i].X + " " + re[0][i].Y + " " + re[0][i].Z + "\r\n";
|
|
}
|
|
if (re.Count > 1)
|
|
{
|
|
txtb += i + " 0" + " " + re[1][i].X + " " + re[1][i].Y + " " + re[1][i].Z + "\r\n";
|
|
}
|
|
if (re.Count > 2)
|
|
{
|
|
txtc += i + " 0" + " " + re[2][i].X + " " + re[2][i].Y + " " + re[2][i].Z + "\r\n";
|
|
}
|
|
txtd += i + " 0" + " " + new_bVecs[i].X + " " + new_bVecs[i].Y + " " + new_bVecs[i].Z + "\r\n";
|
|
|
|
}
|
|
if (re.Count > 0)
|
|
{
|
|
string path = $"C:/Users/szdot/Desktop/a.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
SaveFile(path, txta);
|
|
}
|
|
if (re.Count > 1)
|
|
{
|
|
string path = "C:/Users/szdot/Desktop/b.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
SaveFile(path, txtb);
|
|
}
|
|
if (re.Count > 2)
|
|
{
|
|
string path = "C:/Users/szdot/Desktop/c.txt";
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
SaveFile(path, txtc);
|
|
}
|
|
|
|
string pathd = "C:/Users/szdot/Desktop/d.txt";
|
|
if (File.Exists(pathd))
|
|
{
|
|
File.Delete(pathd);
|
|
}
|
|
SaveFile(pathd, txtd);
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
//绕行取消
|
|
private void ByPassCancel_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
cts.Cancel(); //取消掉 异步执行的 绕行函数
|
|
cts = new CancellationTokenSource();
|
|
}
|
|
// 异步回调函数 输出日志
|
|
private async void StrPrintAsync(string str)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
// 输出日志的异步操作
|
|
StrPrint(str);
|
|
});
|
|
}
|
|
private void StrPrint(string str)
|
|
{
|
|
// 使用 Dispatcher 来确保在 UI 线程上执行更新操作
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
vLogBox.Text += "\r\n" + str;
|
|
// 将滚动条滚动到末尾
|
|
vLogBox.ScrollToEnd();
|
|
});
|
|
}
|
|
private void GetVal(int val)
|
|
{
|
|
}
|
|
/// <summary>
|
|
/// 保存输出文本
|
|
/// </summary>
|
|
private static void SaveFile(string filePath, string txtCon)
|
|
{
|
|
txtCon = txtCon.TrimEnd((char[])"\n\r".ToCharArray());//去除最后的回车符
|
|
Console.WriteLine(txtCon);
|
|
string stream = null;
|
|
if (File.Exists(filePath))
|
|
{
|
|
StreamReader reader = new StreamReader(filePath);
|
|
stream = reader.ReadToEnd();
|
|
reader.Close();
|
|
}
|
|
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate);
|
|
StreamWriter sw = new StreamWriter(fs);
|
|
sw.Write(txtCon);
|
|
sw.Close();
|
|
fs.Close();
|
|
}
|
|
/// <summary>
|
|
/// 航点文件 模型对象
|
|
/// </summary>
|
|
public FcgmJsonModel FcgmInfo { get; set; }
|
|
/// <summary>
|
|
/// 主画布
|
|
/// </summary>
|
|
public MainCanvas TopCanvas { get; set; }
|
|
/// <summary>
|
|
/// 导入航点 在画布上的位置
|
|
/// </summary>
|
|
public Vector3[] PlaneVecOnCanvas { get; set; }
|
|
/// <summary>
|
|
/// 导入的gif路径
|
|
/// </summary>
|
|
public string ImagePath { get; set; }
|
|
/// <summary>
|
|
/// 导入航点
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ImportFcgm_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
//资源管理器 获取航点文件路径
|
|
FileBase.FileClass = new string[] { "航点文件" };
|
|
FileBase.Pascal = new string[] { "*.fcgm" };
|
|
string FliePath = FileBase.OpenExplorer("航点文件导入", out bool isSelect);
|
|
if (!isSelect)
|
|
{
|
|
return;//未打开文件跳出.
|
|
}
|
|
else
|
|
{
|
|
this.FcgmInfo = JsonBase.JsonToModel(FliePath);//Json航点文件 转存到 对象里
|
|
}
|
|
//获取航点
|
|
Vector3[] planesPos = new Vector3[this.FcgmInfo.coptercount];
|
|
int id = 0;
|
|
foreach (var item in this.FcgmInfo.tasks[2].singleCopterInfos)
|
|
{
|
|
planesPos[id] = new Vector3(item.x * 100, item.targetAlt * 100, -item.y * 100);//转换厘米单位
|
|
id++;
|
|
}
|
|
Vector3 planesCenterPos = FlyVecFun.GetPosCenter(planesPos);//获取航点的中心点
|
|
//坐标集合 自适应画布 缩放比例因子
|
|
double[] planesPosWhl = FlyVecFun.GetVecsWithHighLength(planesPos);
|
|
double scale;//比例因子
|
|
if (planesPosWhl[0] > planesPosWhl[2])//宽图
|
|
{
|
|
scale = planesPosWhl[0] / 500;//比例因子
|
|
}
|
|
else//高图
|
|
{
|
|
scale = planesPosWhl[2] / 500;//比例因子
|
|
}
|
|
//在画布创建飞机
|
|
PlaneVecOnCanvas = new Vector3[FcgmInfo.coptercount];
|
|
int planeId = 0;
|
|
foreach (var item in planesPos)
|
|
{
|
|
Vector3 v = item.SetZeroEd(planesCenterPos) / scale + 400;
|
|
TopCanvas.CreatePlanes(v, planeId);
|
|
PlaneVecOnCanvas[planeId] = v;
|
|
planeId++;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 输出航点
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ExportFcgm_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
string jsonStr = JsonBase.ModelTojson(this.FcgmInfo);
|
|
FileBase.FileClass = new string[] { "航点文件" };
|
|
FileBase.Pascal = new string[] { "*.fcgm" };
|
|
FileBase.SaveExplorer(jsonStr);
|
|
}
|
|
/// <summary>
|
|
/// 导入图片
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void ImportImg_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
//资源管理器 获取航点文件路径
|
|
FileBase.FileClass = new string[] { "动态图片", "静态图片" };
|
|
FileBase.Pascal = new string[] { "*.gif", "*.jpeg;*.jpg;*.png" };
|
|
ImagePath = FileBase.OpenExplorer("映射图片导入", out bool isSelect);
|
|
if (!isSelect)
|
|
{
|
|
return;//未打开文件跳出.
|
|
}
|
|
else
|
|
{
|
|
TopCanvas.ImportGif(ImagePath);
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// 渲染输出航点
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void Render_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
ImageUtility img = new ImageUtility(this.ImagePath);
|
|
int id = 0;
|
|
foreach (Vector3 item in PlaneVecOnCanvas)
|
|
{
|
|
List<LedInfos> ledInfos = new List<LedInfos>();
|
|
Color[] colors = img.GetColorsForGifPos((int)item.X, (int)item.Z);
|
|
string c = "";
|
|
foreach (var color in colors)
|
|
{
|
|
if (c != color.ToString().Remove(0, 3))//判断和一帧颜色是否相同 不同的话添加 新的灯光信息
|
|
{
|
|
//添加灯光信息
|
|
LedInfos led = new LedInfos();
|
|
led.Delay = 0.1;
|
|
led.LEDMode = (int)LightClass.常亮;
|
|
led.LEDInterval = 0.0;
|
|
led.LEDRate = 0;
|
|
led.LEDTimes = 0;
|
|
led.LEDRGB = color.ToString().Remove(0, 3);
|
|
ledInfos.Add(led);
|
|
//记录这一帧颜色 用于下次循环时和 这一帧进行对比
|
|
c = color.ToString().Remove(0, 3);
|
|
}
|
|
else//如果和上一帧颜色一样 则不进行Add 并把上一帧的 灯光延时自加0.1秒
|
|
{
|
|
ledInfos[ledInfos.Count - 1].Delay += 0.1;
|
|
}
|
|
|
|
}
|
|
this.FcgmInfo.tasks[2].singleCopterInfos[id].ledInfos = ledInfos;
|
|
id++;
|
|
}
|
|
|
|
MessageBox.Show("成功");
|
|
}
|
|
|
|
|
|
}
|
|
/// <summary>
|
|
/// 灯光 组
|
|
/// </summary>
|
|
public enum LightClass
|
|
{
|
|
常亮 = 0,
|
|
同步闪烁单色 = 1,
|
|
同步闪烁随机 = 2,
|
|
异步闪烁单色 = 3,
|
|
异步闪烁随机 = 4,
|
|
渐亮 = 5,
|
|
渐暗 = 6,
|
|
呼吸灯单色 = 7,
|
|
呼吸灯随机 = 8,
|
|
异步呼吸灯单色 = 9,
|
|
异步呼吸灯随机 = 10,
|
|
变色单色 = 11,
|
|
变色随机 = 12,
|
|
异步变色单色 = 13,
|
|
异步变色随机 = 14,
|
|
拉烟 = 15
|
|
}
|
|
/// <summary>
|
|
/// 画布 渲染
|
|
/// </summary>
|
|
public class MainCanvas
|
|
{
|
|
public Canvas MyCanvas { get; set; }
|
|
public MainCanvas(Canvas canvas)
|
|
{
|
|
this.MyCanvas = canvas;
|
|
}
|
|
/// <summary>
|
|
/// 创建 飞机元素
|
|
/// </summary>
|
|
/// <param name="planePos">指定坐标</param>
|
|
/// <param name="planeId">指定ID</param>
|
|
public void CreatePlanes(Vector3 planePos, int planeId)
|
|
{
|
|
Ellipse plane = new Ellipse();//实例一个圆形
|
|
plane.Width = plane.Height = 13;
|
|
plane.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
|
|
plane.StrokeThickness = 2;
|
|
plane.Stroke = new SolidColorBrush(Color.FromArgb(255, 36, 36, 36));
|
|
plane.Name = "plane" + Convert.ToString(planeId);
|
|
//插入飞机
|
|
MyCanvas.Children.Add(plane);
|
|
Canvas.SetLeft(plane, planePos.X);
|
|
Canvas.SetTop(plane, planePos.Z);
|
|
}
|
|
public void ImportGif(string path)
|
|
{
|
|
string extendName = string.Copy(path);
|
|
string[] extendNameArr = extendName.Split('.');//获取扩展名
|
|
Image img = new Image();
|
|
if (extendNameArr[1] == "gif")
|
|
{
|
|
var image = new BitmapImage();
|
|
image.BeginInit();
|
|
image.UriSource = new Uri(path);
|
|
image.EndInit();
|
|
ImageBehavior.SetAnimatedSource(img, image);
|
|
MyCanvas.Children.Add(img);
|
|
}
|
|
else
|
|
{
|
|
img.Source = new BitmapImage(new Uri(path));
|
|
MyCanvas.Children.Add(img);
|
|
}
|
|
}
|
|
}
|
|
}
|