diff --git a/FlieOperate/FileBase.cs b/FlieOperate/FileBase.cs
index 57c83da..6d78136 100644
--- a/FlieOperate/FileBase.cs
+++ b/FlieOperate/FileBase.cs
@@ -1,4 +1,4 @@
-using FlyBase;
+using FlightRouteV2;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -12,7 +12,7 @@ namespace FlieOperate
///
/// 关于文件的 操作类
///
- public class FileBase
+ public static class FileBase
{
///
/// 逐行读取 文档
diff --git a/FlieOperate/FlieOperate.csproj b/FlieOperate/FlieOperate.csproj
index 768baff..172b145 100644
--- a/FlieOperate/FlieOperate.csproj
+++ b/FlieOperate/FlieOperate.csproj
@@ -31,9 +31,6 @@
4
-
- ..\FlyCube\bin\Release\FlyBase.dll
-
..\FlyCube\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
@@ -59,5 +56,11 @@
+
+
+ {626a9bfa-07de-4063-a178-360eb7057ed6}
+ FlyBase
+
+
\ No newline at end of file
diff --git a/FlyBase/FlyBase.cs b/FlyBase/FlyBase.cs
index 8249903..5ba5bf4 100644
--- a/FlyBase/FlyBase.cs
+++ b/FlyBase/FlyBase.cs
@@ -8,17 +8,19 @@ using System.Net.Http;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Shapes;
using static System.Net.WebRequestMethods;
-namespace FlyBase
+namespace FlightRouteV2
{
//矩阵类
public struct Matrix
@@ -263,8 +265,9 @@ namespace FlyBase
public override bool Equals(object obj)
{
// 检查对象是否与当前向量具有相同的类型
- if (obj is Vector3 vector)
+ if (obj is Vector3)
{
+ Vector3 vector = (Vector3)obj;
// 比较向量的每个分量
return X == vector.X &&
Y == vector.Y &&
@@ -537,19 +540,7 @@ namespace FlyBase
Dictionary> graph = new Dictionary>();
Dictionary visited = new Dictionary();
List> result = new List>();
- void DFS(int node, List connected)
- {
- visited[node] = true;
- connected.Add(node);
-
- foreach (var neighbor in graph[node])
- {
- if (!visited[neighbor])
- {
- DFS(neighbor, connected);
- }
- }
- }
+
// 构建图
foreach (var edge in arr)
{
@@ -572,18 +563,31 @@ namespace FlyBase
if (!visited[node])
{
List connected = new List();
- DFS(node, connected);
+ DFS(node, connected, graph, visited);
result.Add(connected);
}
}
return result;
}
+ private static void DFS(int node, List connected, Dictionary> graph, Dictionary visited)
+ {
+ visited[node] = true;
+ connected.Add(node);
+
+ foreach (var neighbor in graph[node])
+ {
+ if (!visited[neighbor])
+ {
+ DFS(neighbor, connected, graph, visited);
+ }
+ }
+ }
///
/// 获取一组序列的所有排列方式 ps:[0,1,2] 结果[[0, 1, 2],[0, 2, 1],[1, 0, 2],[1, 2, 0],[2, 0, 1],[2, 1, 0]]
///
/// 一组序列
/// 所有序列的排列方式
- public static List> Permutations(List array)
+ private static List> Permutations(List array)
{
List> result = new List>();
GeneratePermutations(array, 0, array.Count - 1, result);
@@ -616,20 +620,12 @@ namespace FlyBase
/// b坐标集合
/// a b集合的对应关系
/// 坐标集合
- private static Vector3[] CreateNewBVecs(Vector3[] aVecs, Vector3[] bVecs, List match)
+ private static Vector3[] CreateNewBVecs(Vector3[] bVecs, List match)
{
- Dictionary indexMap = new Dictionary();
- // 构建索引映射
- foreach (var pair in match)
- {
- indexMap[pair[0]] = pair[1];
- }
- // 根据映射构建新的bb数组
Vector3[] new_bVecs = new Vector3[bVecs.Length];
- foreach (var entry in indexMap)
+ foreach (int[] m in match)
{
- int newIndex = entry.Value;
- new_bVecs[newIndex] = bVecs[entry.Key];
+ new_bVecs[m[0]] = bVecs[m[1]];
}
return new_bVecs;
}
@@ -733,17 +729,17 @@ namespace FlyBase
/// true在一个平面 false不在一个平面
public static bool IsVecsOnPlane(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
{
- // 计算两条边
- Vector3 side1 = vec2 - vec1;
- Vector3 side2 = vec3 - vec2;
- // 计算法线向量
- Vector3 normal = CrossPro(side1, side2);
- // 计算第四个点到第一个点的向量
- Vector3 toPoint4 = vec4 - vec1;
- // 设置容差值,根据具体情况调整
- float tolerance = 0.01f;
- // 判断四个点是否在同一个平面上
- return Math.Abs(DotPro(toPoint4, normal)) < tolerance;
+ //计算三个向量
+ Vector3 v1v2 = vec2 - vec1;
+ Vector3 v1v3 = vec3 - vec1;
+ Vector3 v1v4 = vec4 - vec1;
+ //计算法线向量
+ Vector3 normal_vector = CrossPro(v1v2,v1v3);
+ //计算点到平面的距离
+ double distance = DotPro(normal_vector, v1v4) / normal_vector.GetMag();
+ //设置一个阈值,判断是否共面
+ double epsilon = 0.1;
+ return Math.Abs(distance) < epsilon;
}
///
/// 判断4个点是否在同一条直线上
@@ -753,7 +749,7 @@ namespace FlyBase
/// 点3
/// 点4
/// true在一条直线上 false不在一条直线上
- public static bool IsVecsOnLine(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
+ private static bool IsVecsOnLine(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
{
// 计算相邻点之间的方向向量
Vector3 dir1 = new Vector3(vec2.X - vec1.X, vec2.Y - vec1.Y, vec2.Z - vec1.Z);
@@ -762,7 +758,7 @@ namespace FlyBase
// 检查任意两个相邻方向向量的叉积是否为零
// 这是在三维空间中判断共线的条件
- return CrossPro(dir1, dir2).IsZero() && CrossPro(dir2, dir3).IsZero();
+ return CrossPro(dir1, dir2).GetMag() <0.1 && CrossPro(dir2, dir3).GetMag() <0.1;
}
///
/// 辅助方法,用于检查向量是否为零向量
@@ -774,20 +770,6 @@ namespace FlyBase
return vector.X == 0 && vector.Y == 0 && vector.Z == 0;
}
///
- /// 坐标置换 向量乘以矩阵(i帽j帽k帽)得到置换后的向量坐标 ps:x指向i帽 y轴指向j帽 z轴指向k帽
- ///
- /// 要变换的向量
- /// 矩阵标量 既i帽 j帽 k帽 三点的坐标组成的矩阵 “可以想象成臂长为1的操作轴图标”
- ///
- private static Vector3 MatrixMul(Vector3 vec, Vector3[] mat)
- {
- Vector3 re = new Vector3();//声明返回值
- re.X = vec.X * mat[0].X + vec.Y * mat[1].X + vec.Z * mat[2].X;
- re.Y = vec.X * mat[0].Y + vec.Y * mat[1].Y + vec.Z * mat[2].Y;
- re.Z = vec.X * mat[0].Z + vec.Y * mat[1].Z + vec.Z * mat[2].Z;
- return re;
- }
- ///
/// 获取两条线段 的最近位置的距离和占比
///
/// 线段1起始点
@@ -795,16 +777,8 @@ namespace FlyBase
/// 线段2起始点
/// 线段2起终点
/// [在线段1占比,在线段2占比,最近距离]
- public static double RecentlySquareOfLine(Vector3 a1, Vector3 a2, Vector3 b1, Vector3 b2)
+ private static double RecentlySquareOfLine(Vector3 a1, Vector3 a2, Vector3 b1, Vector3 b2)
{
- bool IsEqual(double x, double y)
- {
- if (Math.Abs(x - y) < 1e-7)
- {
- return true;
- }
- return false;
- }
if (a1 == a2) a2 += 1;// 防止线段长度为0
if (b1 == b2) b2 += 1;
double ux = a2.X - a1.X;
@@ -884,6 +858,14 @@ namespace FlyBase
double dz = wz + (sc * uz) - (tc * vz);
return dx * dx + dy * dy + dz * dz;//两线最近距离的平方
}
+ private static bool IsEqual(double x, double y)
+ {
+ if (Math.Abs(x - y) < 1e-7)
+ {
+ return true;
+ }
+ return false;
+ }
///
/// 按比例在两条线段上截取对应点间的最小距离 平方
///
@@ -892,7 +874,7 @@ namespace FlyBase
/// 线段2起始点
/// 线段2起终点
/// 最小距离的平方值
- public static double MinDistanceSquareOfLine(Vector3 a1, Vector3 a2, Vector3 b1, Vector3 b2)
+ private static double MinDistanceSquareOfLine(Vector3 a1, Vector3 a2, Vector3 b1, Vector3 b2)
{
//相对位置和相对速度
Vector3 d0 = b1 - a1;
@@ -962,7 +944,7 @@ namespace FlyBase
/// 坐标集合
/// 默认返回为true重心 false则为中心
/// 重心或中心坐标
- public static Vector3 GetPosCenter(List pos, bool isCentroid = true)
+ private static Vector3 GetPosCenter(List pos, bool isCentroid = true)
{
int cou = pos.Count;
if (isCentroid)//重心
@@ -1025,25 +1007,25 @@ namespace FlyBase
///
/// 碰撞检测
///
- /// 始点坐标集合
- /// 终点坐标集合
+ /// 始点坐标集合
+ /// 终点坐标集合
/// 航线最小间距平方值
/// 飞行过程中最小间距平方值
///
- public static List AirImitation(Vector3[] startPos, Vector3[] endPos, double lineDistanceSquare = 36100, double spaceBetweenSquare = 48400)
+ private static List AirImitation(Vector3[] aVecs, Vector3[] bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 650000)
{
List planesCollision = new List(); //所有碰撞的组
- int planeCou = startPos.Length; //获取飞机总数
+ int planeCou = aVecs.Length; //获取飞机总数
for (int a = 0; a < planeCou; a++)
{
for (int b = 0; a + 1 + b < planeCou; b++)
{
//判断两条轨迹 之间的最小距离
- double distanceSquare = RecentlySquareOfLine(startPos[a], endPos[a], startPos[a + 1 + b], endPos[a + 1 + b]);
+ double distanceSquare = RecentlySquareOfLine(aVecs[a], bVecs[a], aVecs[a + 1 + b], bVecs[a + 1 + b]);
if (distanceSquare < lineDistanceSquare)
{
//判断飞机距离是否过近
- double planeLenSquare = MinDistanceSquareOfLine(startPos[a], endPos[a], startPos[a + 1 + b], endPos[a + 1 + b]);
+ double planeLenSquare = MinDistanceSquareOfLine(aVecs[a], bVecs[a], aVecs[a + 1 + b], bVecs[a + 1 + b]);
if (planeLenSquare < spaceBetweenSquare)
{
planesCollision.Add(new int[] { a, a + 1 + b });
@@ -1056,25 +1038,25 @@ namespace FlyBase
///
/// 碰撞检测
///
- /// 始点坐标集合
- /// 终点坐标集合
+ /// 始点坐标集合
+ /// 终点坐标集合
/// 航线最小间距平方值
/// 飞行过程中最小间距平方值
///
- public static List AirImitation(List startPos, List endPos, double lineDistanceSquare = 36100, double spaceBetweenSquare = 48400)
+ private static List AirImitation(List aVecs, List bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 650000)
{
List planesCollision = new List(); //所有碰撞的组
- int planeCou = startPos.Count; //获取飞机总数
+ int planeCou = aVecs.Count; //获取飞机总数
for (int a = 0; a < planeCou; a++)
{
for (int b = 0; a + 1 + b < planeCou; b++)
{
//判断两条轨迹 之间的最小距离
- double distanceSquare = RecentlySquareOfLine(startPos[a], endPos[a], startPos[a + 1 + b], endPos[a + 1 + b]);
+ double distanceSquare = RecentlySquareOfLine(aVecs[a], bVecs[a], aVecs[a + 1 + b], bVecs[a + 1 + b]);
if (distanceSquare < lineDistanceSquare)
{
//判断飞机距离是否过近
- double planeLenSquare = MinDistanceSquareOfLine(startPos[a], endPos[a], startPos[a + 1 + b], endPos[a + 1 + b]);
+ double planeLenSquare = MinDistanceSquareOfLine(aVecs[a], bVecs[a], aVecs[a + 1 + b], bVecs[a + 1 + b]);
if (planeLenSquare < spaceBetweenSquare)
{
planesCollision.Add(new int[] { a, a + 1 + b });
@@ -1088,22 +1070,22 @@ namespace FlyBase
/// 单机碰撞检测
///
/// 飞机的id PS:id从0开始
- /// 飞机起始坐标集合
- /// 飞机终点坐标集合
+ /// 飞机起始坐标集合
+ /// 飞机终点坐标集合
/// 航线小距离的平方对比值
/// 飞行过程中最小间距的平方对比值
/// true:有碰撞 false:无碰撞
- public static bool OnlyImitation(int onlyPlaneId, Vector3[] startPos, Vector3[] endPos, double lineDistanceSquare = 32400, double spaceBetweenSquare = 90000)
+ private static bool OnlyImitation(int onlyPlaneId, Vector3[] aVecs, Vector3[] bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 250000)
{
//选出与指定飞机 航线有交叉的飞机 用于模拟飞行碰撞检测
- for (int contrastId = 0; contrastId < startPos.Length; contrastId++)
+ for (int contrastId = 0; contrastId < aVecs.Length; contrastId++)
{
if (onlyPlaneId == contrastId) continue;//不和自己比较
// 判断两条轨迹 之间的最小距离
- double distanceSquare = RecentlySquareOfLine(startPos[onlyPlaneId], endPos[onlyPlaneId], startPos[contrastId], endPos[contrastId]);//航线最小距离
+ double distanceSquare = RecentlySquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//航线最小距离
if (distanceSquare < lineDistanceSquare)
{
- double minDistanceSquare = MinDistanceSquareOfLine(startPos[onlyPlaneId], endPos[onlyPlaneId], startPos[contrastId], endPos[contrastId]);//按比例飞行最小间距
+ double minDistanceSquare = MinDistanceSquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//按比例飞行最小间距
if (minDistanceSquare < spaceBetweenSquare)
{
return true;//返回有碰撞
@@ -1116,22 +1098,78 @@ namespace FlyBase
/// 单机碰撞检测
///
/// 飞机的id PS:id从0开始
- /// 飞机起始坐标集合
- /// 飞机终点坐标集合
+ /// 飞机起始坐标集合
+ /// 飞机终点坐标集合
/// 航线小距离的平方对比值
/// 飞行过程中最小间距的平方对比值
/// true:有碰撞 false:无碰撞
- public static bool OnlyImitation(int onlyPlaneId, List startPos, List endPos, double lineDistanceSquare = 32400, double spaceBetweenSquare = 90000)
+ private static bool OnlyImitation(int onlyPlaneId, List aVecs, List bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 250000)
{
//选出与指定飞机 航线有交叉的飞机 用于模拟飞行碰撞检测
- for (int contrastId = 0; contrastId < startPos.Count; contrastId++)
+ for (int contrastId = 0; contrastId < aVecs.Count; contrastId++)
{
if (onlyPlaneId == contrastId) continue;//不和自己比较
// 判断两条轨迹 之间的最小距离
- double distanceSquare = RecentlySquareOfLine(startPos[onlyPlaneId], endPos[onlyPlaneId], startPos[contrastId], endPos[contrastId]);//航线最小距离
+ double distanceSquare = RecentlySquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//航线最小距离
if (distanceSquare < lineDistanceSquare)
{
- double minDistanceSquare = MinDistanceSquareOfLine(startPos[onlyPlaneId], endPos[onlyPlaneId], startPos[contrastId], endPos[contrastId]);//按比例飞行最小间距
+ double minDistanceSquare = MinDistanceSquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//按比例飞行最小间距
+ if (minDistanceSquare < spaceBetweenSquare)
+ {
+ return true;//返回有碰撞
+ }
+ }
+ }
+ return false;//返回没有碰撞;
+ }
+ ///
+ /// 单机碰撞检测
+ ///
+ /// 飞机的id PS:id从0开始
+ /// 飞机起始坐标集合
+ /// 飞机终点坐标集合
+ /// 航线小距离的平方对比值
+ /// 飞行过程中最小间距的平方对比值
+ /// true:有碰撞 false:无碰撞
+ private static bool OnlyImitation(int onlyPlaneId, Vector3[] aVecs, List bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 250000)
+ {
+ //选出与指定飞机 航线有交叉的飞机 用于模拟飞行碰撞检测
+ for (int contrastId = 0; contrastId < aVecs.Length; contrastId++)
+ {
+ if (onlyPlaneId == contrastId) continue;//不和自己比较
+ // 判断两条轨迹 之间的最小距离
+ double distanceSquare = RecentlySquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//航线最小距离
+ if (distanceSquare < lineDistanceSquare)
+ {
+ double minDistanceSquare = MinDistanceSquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//按比例飞行最小间距
+ if (minDistanceSquare < spaceBetweenSquare)
+ {
+ return true;//返回有碰撞
+ }
+ }
+ }
+ return false;//返回没有碰撞;
+ }
+ ///
+ /// 单机碰撞检测
+ ///
+ /// 飞机的id PS:id从0开始
+ /// 飞机起始坐标集合
+ /// 飞机终点坐标集合
+ /// 航线小距离的平方对比值
+ /// 飞行过程中最小间距的平方对比值
+ /// true:有碰撞 false:无碰撞
+ private static bool OnlyImitation(int onlyPlaneId, List aVecs, Vector3[] bVecs, double lineDistanceSquare = 36100, double spaceBetweenSquare = 250000)
+ {
+ //选出与指定飞机 航线有交叉的飞机 用于模拟飞行碰撞检测
+ for (int contrastId = 0; contrastId < aVecs.Count; contrastId++)
+ {
+ if (onlyPlaneId == contrastId) continue;//不和自己比较
+ // 判断两条轨迹 之间的最小距离
+ double distanceSquare = RecentlySquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//航线最小距离
+ if (distanceSquare < lineDistanceSquare)
+ {
+ double minDistanceSquare = MinDistanceSquareOfLine(aVecs[onlyPlaneId], bVecs[onlyPlaneId], aVecs[contrastId], bVecs[contrastId]);//按比例飞行最小间距
if (minDistanceSquare < spaceBetweenSquare)
{
return true;//返回有碰撞
@@ -1143,11 +1181,13 @@ namespace FlyBase
///
/// 智能路径 规则:找ab组共同最外圈的点 然后对应找a或b里面最近点 为一组匹配 最后进行碰撞交叉互换
///
- /// 起始点坐标组
- /// 目标点坐标组
+ /// 起始点坐标组
+ /// 目标点坐标组
+ /// 日志输出 回调函数
/// 交换次数
- ///
- public static Vector3[] ContactABOut(Vector3[] aVecs, Vector3[] bVecs, int swapCount = 5)
+ /// 交叉线路数量上限 ps:超过这个数量则不进行交换
+ /// 新的目标点
+ public static Vector3[] ContactABOut(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint, int swapCount = 5, int crossingLimit = 6)
{
int planeCou = aVecs.Length; // 飞机总数
List match = new List(); // ab对应关系
@@ -1162,6 +1202,7 @@ namespace FlyBase
// 遍历找出 AB集合对应关系
for (int k = 0; k < planeCou; k++)
{
+
// 遍历每次刷新 剩下为未匹配总数
int remainCou = aIndex.Count;
// 遍历每次刷新 重心
@@ -1185,7 +1226,6 @@ namespace FlyBase
int bMaxIndex = GetIndexOfMaxOrMin(bLens); // b集合到重心点最长的距离 数组的下标
if (aLens[aMaxIndex] > bLens[bMaxIndex])//找出 最外层如果为A集合点 对应B集合最近点 的下标
{
- //MessageBox.Show(aIndex[aMaxIndex].ToString());
double[] outAtoBLen = new double[remainCou];//最外层A点到 B集合所有点的距离
for (int i = 0; i < remainCou; i++)
{
@@ -1209,8 +1249,7 @@ namespace FlyBase
bIndex.RemoveAt(bMaxIndex); // 删除已经配对的b集合 ID
}
}
- Vector3[] new_bVecs = CreateNewBVecs(aVecs, bVecs, match);// 按照映射 获取a 对应的 新的b集合
- return new_bVecs;
+ Vector3[] new_bVecs = CreateNewBVecs(bVecs, match);// 按照映射 获取a 对应的 新的b集合
//交叉 交换
for (int i = 0; i < swapCount; i++)
@@ -1220,7 +1259,7 @@ namespace FlyBase
// 遍历所有交叉组 分组做交换
foreach (List swap_indices in formatCollision)
{
- if (swap_indices.Count <= 6) // 只尝试5组交叉碰撞以下的航线互换
+ if (swap_indices.Count <= crossingLimit) // 只尝试5组交叉碰撞以下的航线互换
{
//交叉 生成所有排列
List> all_permutations = Permutations(swap_indices);
@@ -1244,7 +1283,7 @@ namespace FlyBase
tempLen.Add(AirImitation(aVecs, current_array).Count);// 迭代 记录所有排列的碰撞次数
tempNew_bVecsS.Add(current_array); //迭代 记录所有排列交换之后的目标坐标集
}
- new_bVecs = tempNew_bVecsS[GetRandomMinIndex(tempLen)];
+ new_bVecs = tempNew_bVecsS[GetRandomMinIndex(tempLen)].ToArray();
}
}
}
@@ -1253,44 +1292,55 @@ namespace FlyBase
///
/// 智能挫层
///
- /// 起始坐标集合
- /// 终点做标集合
+ /// 起始坐标集合
+ /// 终点做标集合
+ /// 日志输出 回调函数
/// 挫层层高
/// 返回一个二维向量坐标集合 middle[0]是第一个中间航点 middle[1]是第二个中间航点 返回空数组则代表两个图形不在一个平面上或者不够4个点
- public static List CollisionLayer(Vector3[] startPos, Vector3[] endPos, double layHight = 220)
+ public static List CollisionLayer(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint, double layHight = 220)
{
List re = new List();
//获取飞机总数
- int planeCou = startPos.Length;
- //检测两个图形是否在一个平面上
- Vector3[] allPos = startPos.Concat(endPos).ToArray();//合并两个集合
- List ppppVecArr = RandomSel4Vec(allPos);//随机选择
- if (ppppVecArr.Count == 0)//两个图形不够四个点 返回 空数组
+ int planeCou = aVecs.Length;
+ if (planeCou < 2)//至少不少于2架飞机 才开始挫层
{
+ StrPrint("图案至少要两个点阵!");
return re;
}
- // 使用 foreach 遍历 List 中的元素
- foreach (Vector3[] pppVec in ppppVecArr)
+ //检测两个图形是否在一个平面上
+ Vector3 vec0 = new Vector3(0, 0, 0);
+ Vector3 vec1 = new Vector3(0, 0, 0);
+ Vector3 vec2 = new Vector3(0, 0, 0);
+ Vector3 vec3 = new Vector3(0, 0, 0);
+
+ //遍历所有点 查看是不是都再一个平面内
+ for (int i = 0; i < planeCou; i++)
{
- if (!(IsVecsOnPlane(pppVec[0], pppVec[1], pppVec[2], pppVec[3])))
+ vec0 = aVecs[i]; vec1 = bVecs[planeCou - i - 1]; vec2 = aVecs[planeCou - i - 1]; vec3 = bVecs[i];
+ if (!(IsVecsOnPlane(vec0, vec1, vec2, vec3)))
{
+ StrPrint("图案不在一个平面!");
return re;//两个图形不在一个平面上 返回 空数组
}
-
+ else
+ {
+ break;
+ }
}
//遍历选出4个不共线的点 ps:方便后续叉积算法线标量
- bool isVecsOnLine = false; Vector3 vec0 = new Vector3(0, 0, 0); Vector3 vec1 = new Vector3(0, 0, 0); Vector3 vec2 = new Vector3(0, 0, 0); Vector3 vec3 = new Vector3(0, 0, 0);
+ bool isVecsOnLine = false;
for (int i = 0; i < planeCou; i++) //遍历所有点 找出不在一条直线上的四个点
{
- vec0 = startPos[i]; vec1 = endPos[planeCou - i - 1]; vec2 = startPos[planeCou - i - 1]; vec3 = endPos[i];
+ vec0 = aVecs[i]; vec1 = bVecs[planeCou - i - 1]; vec2 = aVecs[planeCou - i - 1]; vec3 = bVecs[i];
isVecsOnLine = IsVecsOnLine(vec0, vec1, vec2, vec3);
- if (isVecsOnLine)
+ if (!isVecsOnLine)
{
break;
}
}
if (isVecsOnLine)
{
+ StrPrint("所有点都在一条直线上!");
return re;//两个图案的所有点都在一条直线上 返回 空数组
}
//检查完毕后
@@ -1303,35 +1353,37 @@ namespace FlyBase
for (int i = 0; i < planeCou; i++)
{
int shiftCou = 1; //记录循环次数 即层数
- Vector3 aOrigin = startPos[i]; //原点位置
- Vector3 bOrigin = endPos[i]; //原点位置
- while (OnlyImitation(i, startPos, endPos))
+ Vector3 aOrigin = aVecs[i]; //原点位置
+ Vector3 bOrigin = bVecs[i]; //原点位置
+ while (OnlyImitation(i, aVecs, bVecs))
{
Vector3 shiftVec = normalScalar * ((shiftCou + 1) / 2 * layHight);
if (shiftCou % 2 == 1)
{
- startPos[i] = aOrigin + shiftVec;
- endPos[i] = bOrigin + shiftVec;
+ aVecs[i] = aOrigin + shiftVec;
+ bVecs[i] = bOrigin + shiftVec;
}
else
{
- startPos[i] = aOrigin - shiftVec;
- endPos[i] = bOrigin - shiftVec;
+ aVecs[i] = aOrigin - shiftVec;
+ bVecs[i] = bOrigin - shiftVec;
}
shiftCou += 1;
}
}
- re.Add(startPos);
- re.Add(endPos);
+ StrPrint("挫层完成!");
+ re.Add(aVecs);
+ re.Add(bVecs);
return re;
}
///
/// 路径绕行
///
- /// 起始坐标集合
- /// 终点做标集合
- /// 返回一个二维数组 长度为1即1个中间航点 长度为3即前中后三个中间航点
- public static List> ABypassB(Vector3[] aVecs, Vector3[] bVecs)
+ /// 起始坐标集合
+ /// 终点做标集合
+ /// 日志输出 回调函数
+ /// 返回一个二维数组 返回值长度0绕行失败 长度1为一个中间航点 长度为3为三个中间航点顺序(前中后)
+ public static List> ABypassB(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint)
{
List> re = new List>();
int planeCou = aVecs.Length;
@@ -1355,29 +1407,23 @@ namespace FlyBase
List firstCollisionGroup = new List(); //有碰撞飞机列表(第一次绕行)
for (int i = 0; i < planeCou; i++)
{
- bool isPassMark = false;//初始标记
+ StrPrint($"第一次绕行进度:{(int)((double)i/planeCou*100)}%");
+ bool isPassMark = false; //初始标记
int index = sortedIndices[i];//从内到外排序的索引
tempAVecs.Add(aVecs[index]);
tempBVecs.Add(bVecs[index]);
if (i == 0) //如果是第一条航线 直接添加中间航点
{
middleVecs.Add(SetMiddleVec(aVecs[index], bVecs[index])); //添加中间航点
+ continue; //跳出 继续第二条航线计算
}
else //从第二条开始绕
{
middleVecs.Add(SetMiddleVec(aVecs[index], bVecs[index])); // 添加默认中间航点
// 首次默认中间航点检测
- if (!(OnlyImitation(i, tempAVecs, middleVecs))) //前半段碰 碰撞检测
+ if (!(OnlyImitation(i, tempAVecs, middleVecs)) && !(OnlyImitation(i, middleVecs, tempBVecs))) //前半段碰 碰撞检测
{
- if (!(OnlyImitation(i, middleVecs, tempBVecs))) //后半段碰 碰撞检测
- {
- isPassMark = true; //中间航点
- continue; //不撞则跳出 进行下一航线的绕行
- }
- else
- {
- middleVecs.RemoveAt(i); //碰撞检测未通过删除临时中间航点
- }
+ continue; //不撞则跳出 进行下一航线的绕行
}
else
{
@@ -1387,19 +1433,12 @@ namespace FlyBase
List ringVecs = GetRingVec(aVecs[index], bVecs[index], 0.5); //所有可绕行的中间航点集合
foreach (Vector3 v in ringVecs)
{
- middleVecs.Add(v);
+ middleVecs.Add(v); //添加临时绕行航点
//检测
- if (!(OnlyImitation(i, tempAVecs, middleVecs))) //前半段碰 碰撞检测
+ if (!(OnlyImitation(i, tempAVecs, middleVecs)) && !(OnlyImitation(i, middleVecs, tempBVecs))) //前半段碰 碰撞检测
{
- if (!(OnlyImitation(i, middleVecs, tempBVecs))) //后半段碰 碰撞检测
- {
- isPassMark = true; //中间航点 碰撞检测通过标记
- break; //不撞则跳出 进行下一航线的绕行
- }
- else
- {
- middleVecs.RemoveAt(i); //碰撞检测未通过删除临时中间航点
- }
+ isPassMark = true; //中间航点 碰撞检测通过标记
+ break; //不撞则跳出 进行下一航线的绕行
}
else
{
@@ -1407,22 +1446,39 @@ namespace FlyBase
}
}
}
- if (!(isPassMark)) // 如果绕行失败 添加一个默认中间航点
+ // 如果绕行失败
+ if (!isPassMark)
{
- middleVecs.Add(SetMiddleVec(aVecs[index], bVecs[index]));
+ middleVecs.Add(SetMiddleVec(aVecs[index], bVecs[index])); //添加一个默认中间航点
firstCollisionGroup.Add(index);
}
}
- //中间航点坐标集 按飞机id顺序重新映射 ps:恢复原id映射
- middleVecs = sortedIndices.Select(index => middleVecs[index]).ToList();
+ //中间航点坐标集 按飞机id顺序重新映射 ps:恢复原id映射 排序
+ Vector3[] tempMiddleVecs = new Vector3[planeCou];
+ for (int i = 0; i < planeCou; i++)
+ {
+ tempMiddleVecs[sortedIndices[i]] = middleVecs[i];
+ }
+ middleVecs = new List(tempMiddleVecs);
//没有碰撞 返回一个中间航点 并返回
if (firstCollisionGroup.Count == 0)
{
+ StrPrint("第一次绕行通过!");
re.Add(middleVecs);
return re;
}
+ else
+ {
+ string str = "";
+ foreach (int v in firstCollisionGroup) {
+ str += v.ToString() + "号,";
+ }
+ str += "有碰撞,共" + firstCollisionGroup.Count.ToString() + "架!";
+ StrPrint(str);
+ StrPrint("第一次绕行未通过,准备开始第二次绕行!");
+ }
- //第二次绕行 ps:有碰撞进行第二次 前后再各加以航点 嵌套迭代
+ //第二次绕行 ps:有碰撞进行第二次 前后再各加一航点 嵌套迭代
List firstMiddleVecs = new List(); //前中间航点
List secondMiddleVecs = new List(); //后中间航点
List secondCollisionGroup = new List(); //最终有碰撞飞机列表
@@ -1431,8 +1487,11 @@ namespace FlyBase
firstMiddleVecs.Add(SetMiddleVec(aVecs[i], middleVecs[i], 0));
secondMiddleVecs.Add(SetMiddleVec(middleVecs[i], bVecs[i], 1));
}
+ int z = 0;//计算进度
foreach (int index in firstCollisionGroup)
{
+ z++;//计算进度
+ StrPrint($"第二次绕行进度:{(int)((double)z / firstCollisionGroup.Count * 100)}%");
bool isPassMark = false;
// 正中 绕行列表
List ringVecs = GetRingVec(aVecs[index], bVecs[index], 0.5); //所有可绕行的中间航点集合
@@ -1447,20 +1506,49 @@ namespace FlyBase
foreach (Vector3 sr in secondRingVecs)
{
secondMiddleVecs[index] = sr; //后中点逐点
- // 检测
- if (!(OnlyImitation(index, aVecs, firstMiddleVecs))){
+ // 检测 起点到 第一中间航点
+ if (!(OnlyImitation(index, aVecs, firstMiddleVecs)) && !(OnlyImitation(index, firstMiddleVecs, middleVecs)) && !(OnlyImitation(index, middleVecs, secondMiddleVecs)) && !(OnlyImitation(index, secondMiddleVecs, bVecs)))
+ {
+ isPassMark = true; //碰撞检测通过标记
+ break; //不撞则跳出 进行下一航线的绕行
}
- //if not(self.onlyImitation(v, aVecs, firstMiddleVecs)): #前半段碰 碰撞检测
- // if not(self.onlyImitation(v, firstMiddleVecs, middleVecs)):#后半段碰 碰撞检测
- // if not(self.onlyImitation(v, middleVecs, secondMiddleVecs)): #前半段碰 碰撞检测
- // if not(self.onlyImitation(v, secondMiddleVecs, bVecs)):#后半段碰 碰撞检测
- // isPassMark = True #碰撞检测通过标记
- // break #不撞则跳出 进行下一航线的绕行
+ }
+ if (isPassMark)
+ {
+ break; //不撞则跳出 进行下一航线的绕行
}
}
+ if (isPassMark)
+ {
+ break; //不撞则跳出 进行下一航线的绕行
+ }
+ }
+ if (!isPassMark) //如果绕行失败 添加一个默认中间航点
+ {
+ middleVecs[index] = SetMiddleVec(aVecs[index], bVecs[index]); //添加中间航点
+ firstMiddleVecs[index] = SetMiddleVec(aVecs[index], middleVecs[index], 0); // 添加中间航点
+ secondMiddleVecs[index] = SetMiddleVec(middleVecs[index], bVecs[index], 1); // 添加中间航点
+ secondCollisionGroup.Add(index);// 二次绕行仍不通过 添加到列表 (暂时无用)
}
}
-
+ if (secondCollisionGroup.Count == 0)//如果二次绕行通过 添加中间三航点
+ {
+ re.Add(firstMiddleVecs);
+ re.Add(middleVecs);
+ re.Add(secondMiddleVecs);
+ StrPrint("第二次绕行通过!");
+ }
+ else
+ {
+ string str = "";
+ foreach (int v in secondCollisionGroup)
+ {
+ str += v.ToString() + "号,";
+ }
+ str += "仍有碰撞,共" + secondCollisionGroup.Count.ToString() + "架!";
+ StrPrint(str);
+ StrPrint("第二次绕行仍未通过!");
+ }
return re;
}
///
@@ -1469,7 +1557,7 @@ namespace FlyBase
/// 大圆半径
/// 固定弦长 ps:这个值决定绕行点一圈的密集成都值越小越密集
///
- public static List GetVecsOnCircle(double radius, double chordLength = 220)
+ private static List GetVecsOnCircle(double radius, double chordLength = 220)
{
List vecs = new List();
// 计算圆的周长
@@ -1498,7 +1586,7 @@ namespace FlyBase
/// 偏移次数 从0开始,每+1在中点前后往返偏移
/// 偏移层高
/// 矩阵
- public static Matrix GetBasisMatrix(Vector3 aVec, Vector3 bVec, double middleProportion = 0.5, int offCount = 0, double layHight = 220)
+ private static Matrix GetBasisMatrix(Vector3 aVec, Vector3 bVec, double middleProportion = 0.5, int offCount = 0, double layHight = 220)
{
// 计算前向向量 k帽
Vector3 k_hat = (bVec - aVec).NormalizEd();
@@ -1542,7 +1630,7 @@ namespace FlyBase
/// 传递圈函数的弦长 向量矩阵函数的层高
/// 绕行航点范围 ps:绕行中间航点肚子(值越大肚子越小)
///
- public static List GetRingVec(Vector3 aVec, Vector3 bVec, double middleProportion, double transfer = 220, double paunch = 3)
+ private static List GetRingVec(Vector3 aVec, Vector3 bVec, double middleProportion, double transfer = 220, double paunch = 3)
{
List ringVec = new List(); //记录所有绕行中间航点坐标
// 根据a到b的长度 算出中间绕行几圈
diff --git a/FlyCube/FlyCube.csproj b/FlyCube/FlyCube.csproj
index 9dbef46..e8bfd55 100644
--- a/FlyCube/FlyCube.csproj
+++ b/FlyCube/FlyCube.csproj
@@ -98,6 +98,7 @@
ResXFileCodeGenerator
Resources.Designer.cs
+
SettingsSingleFileGenerator
diff --git a/FlyCube/FlyCube.sln b/FlyCube/FlyCube.sln
index cda8c92..7df902b 100644
--- a/FlyCube/FlyCube.sln
+++ b/FlyCube/FlyCube.sln
@@ -8,9 +8,6 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlyBase", "..\FlyBase\FlyBase.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlieOperate", "..\FlieOperate\FlieOperate.csproj", "{C354FD6B-5863-4246-BB48-6DF14A85C161}"
- ProjectSection(ProjectDependencies) = postProject
- {626A9BFA-07DE-4063-A178-360EB7057ED6} = {626A9BFA-07DE-4063-A178-360EB7057ED6}
- EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/FlyCube/MainWindow.xaml b/FlyCube/MainWindow.xaml
index eec7bd5..9753047 100644
--- a/FlyCube/MainWindow.xaml
+++ b/FlyCube/MainWindow.xaml
@@ -21,7 +21,8 @@
-
+
+
\ No newline at end of file
diff --git a/FlyCube/MainWindow.xaml.cs b/FlyCube/MainWindow.xaml.cs
index 6628e70..daa5c2c 100644
--- a/FlyCube/MainWindow.xaml.cs
+++ b/FlyCube/MainWindow.xaml.cs
@@ -13,18 +13,20 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
-using FlyBase;
+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;
namespace FlyCube
{
public partial class MainWindow : Window
{
+ private TextBox LOG;
///
/// 入口函数
///
@@ -33,53 +35,64 @@ namespace FlyCube
InitializeComponent();
//创建一个 主画布对象
TopCanvas = new MainCanvas(this.LayerPlane);
+
}
- private void Del_Click(object sender, RoutedEventArgs e)
+ ///
+ /// 3D绕行
+ ///
+ private void ByPass_Click(object sender, RoutedEventArgs e)
{
- Vector3 a1 = new Vector3(0, 50, 220);
- Vector3 a2 = new Vector3(0, 0, 0);
- Vector3 a3 = new Vector3(0, 1000, 1000);
- Vector3 a4 = new Vector3(1020, 0, 1000);
- Vector3 a5 = new Vector3(1020, 0, 2240);
- Vector3 a6 = new Vector3(1400, 2000, 4500);
-
- Vector3 b1 = new Vector3(420, 0, 330);
- Vector3 b2 = new Vector3(310, 0, 1400);
- Vector3 b3 = new Vector3(120, 0, 4200);
- Vector3 b4 = new Vector3(2330, 0, 7300);
- Vector3 b5 = new Vector3(110, 0, 1400);
- Vector3 b6 = new Vector3(1200, 0, 5200);
- Vector3[] aa = new Vector3[] { a1, a2, a3, a4, a5, a6 };
- Vector3[] bb = new Vector3[] { b1, b2, b3, b4, b5, b6 };
-
- //FlyVecFun.GetRingVec(a1, a6, 0.5);
- //return;
- List a = FlyVecFun.GetRingVec(a1, a6, 0.5);
- //foreach (int[] v in cc)
- //{
- // MessageBox.Show($"{ v[0].ToString()}----{v[1].ToString()}");
- //}
-
- //Vector3[] cc = FlyVecFun.ContactABOut(aa,bb);
- //foreach (var item in a)
- //{
- // MessageBox.Show(item.PosToString());
- //}
- //MessageBox.Show($"{a[0].ToString()}---{a[1].ToString()}---{a[2].ToString()}---{a[3].ToString()}");
- string str = "";
- int id = 1;
- foreach (Vector3 item in a)
+ //资源管理器 获取航点文件路径
+ FileBase.FileClass = new string[] { "航点文件" };
+ FileBase.Pascal = new string[] { "*.txt" };
+ string FliePath = FileBase.OpenExplorer("航点文件导入", out bool isSelect);
+ if (isSelect)
{
- str += id + " 0" + " " + item.X + " " + item.Y + " " + item.Z + "\r\n";
- id++;
+ List 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);
+ List> re = FlyVecFun.ABypassB(aVecs, new_bVecs, StrPrint);
+ if (re.Count == 0)
+ {
+ return;
+ }
+
+ string txta = "";
+ string txtb = "";
+ string txtc = "";
+
+ for (int i = 0; i < abVecs[0].Length; i++)
+ {
+ 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";
+ txtc += i + " 0" + " " + re[2][i].X + " " + re[2][i].Y + " " + re[2][i].Z + "\r\n";
+ }
+
+ }
+ SaveFile("C:/Users/szdot/Desktop/a.txt", txta);
+ if (re.Count > 1)
+ {
+ SaveFile("C:/Users/szdot/Desktop/b.txt", txtb);
+ SaveFile("C:/Users/szdot/Desktop/c.txt", txtc);
+ }
+ }
+ else
+ {
+ return;
}
- //for (int i = 0; i < 4; i++)
- //{
- // str += i + " 0" + " " + a[i].X + " " + a[i].Y + " " + a[i].Z + "\r\n";
- //}
- SaveFile("C:/Users/szdot/Desktop/del.txt", str);
}
- //保存输出文本
+ //回调函数 输出日志
+ private void StrPrint(string str)
+ {
+ //MessageBox.Show(str);
+ vLogBox.Text += "\r\n" + str;
+ }
+ ///
+ /// 保存输出文本
+ ///
private static void SaveFile(string filePath, string txtCon)
{
txtCon = txtCon.TrimEnd((char[])"\n\r".ToCharArray());//去除最后的回车符
@@ -123,7 +136,7 @@ namespace FlyCube
//资源管理器 获取航点文件路径
FileBase.FileClass = new string[] { "航点文件" };
FileBase.Pascal = new string[] { "*.fcgm" };
- string FliePath = FileBase.OpenExplorer("航点文件导入",out bool isSelect);
+ string FliePath = FileBase.OpenExplorer("航点文件导入", out bool isSelect);
if (!isSelect)
{
return;//未打开文件跳出.
@@ -137,10 +150,10 @@ namespace FlyCube
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);//转换厘米单位
+ planesPos[id] = new Vector3(item.x * 100, item.targetAlt * 100, -item.y * 100);//转换厘米单位
id++;
}
- Vector3 planesCenterPos=FlyVecFun.GetPosCenter(planesPos);//获取航点的中心点
+ Vector3 planesCenterPos = FlyVecFun.GetPosCenter(planesPos);//获取航点的中心点
//坐标集合 自适应画布 缩放比例因子
double[] planesPosWhl = FlyVecFun.GetVecsWithHighLength(planesPos);
double scale;//比例因子
@@ -183,8 +196,8 @@ namespace FlyCube
private void ImportImg_Click(object sender, RoutedEventArgs e)
{
//资源管理器 获取航点文件路径
- FileBase.FileClass = new string[] { "动态图片","静态图片" };
- FileBase.Pascal = new string[] { "*.gif","*.jpeg;*.jpg;*.png"};
+ FileBase.FileClass = new string[] { "动态图片", "静态图片" };
+ FileBase.Pascal = new string[] { "*.gif", "*.jpeg;*.jpg;*.png" };
ImagePath = FileBase.OpenExplorer("映射图片导入", out bool isSelect);
if (!isSelect)
{
@@ -194,7 +207,7 @@ namespace FlyCube
{
TopCanvas.ImportGif(ImagePath);
}
-
+
}
///
/// 渲染输出航点
@@ -239,6 +252,7 @@ namespace FlyCube
MessageBox.Show("成功");
}
+
}
///
/// 灯光 组
@@ -262,10 +276,9 @@ namespace FlyCube
异步变色随机 = 14,
拉烟 = 15
}
-
- ///
- /// 画布 渲染
- ///
+ ///
+ /// 画布 渲染
+ ///
public class MainCanvas
{
public Canvas MyCanvas { get; set; }
@@ -296,7 +309,7 @@ namespace FlyCube
string extendName = string.Copy(path);
string[] extendNameArr = extendName.Split('.');//获取扩展名
Image img = new Image();
- if (extendNameArr[1]=="gif")
+ if (extendNameArr[1] == "gif")
{
var image = new BitmapImage();
image.BeginInit();
@@ -305,7 +318,7 @@ namespace FlyCube
ImageBehavior.SetAnimatedSource(img, image);
MyCanvas.Children.Add(img);
}
- else
+ else
{
img.Source = new BitmapImage(new Uri(path));
MyCanvas.Children.Add(img);