Compare commits
10 Commits
84a4baf1f2
...
49484ca152
Author | SHA1 | Date | |
---|---|---|---|
![]() |
49484ca152 | ||
![]() |
ee1f47a448 | ||
![]() |
cf4a484d64 | ||
![]() |
bb6ca71c78 | ||
![]() |
4cd26f6b62 | ||
![]() |
3a6de2e67f | ||
![]() |
aa30959d71 | ||
![]() |
b53fa88b7d | ||
![]() |
48bdb1e650 | ||
![]() |
2944715bab |
@ -411,7 +411,7 @@ namespace FlightRouteV2
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 飞行过程中间距 平方值
|
/// 飞行过程中间距 平方值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static double SpaceBetweenSquare { get; set; } = 62500;
|
public static double SpaceBetweenSquare { get; set; } = 250000;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 算绕行时 中间取点 true在正中间取点即 一个圆盘 false在一个圆柱体内取点
|
/// 算绕行时 中间取点 true在正中间取点即 一个圆盘 false在一个圆柱体内取点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -558,7 +558,7 @@ namespace FlightRouteV2
|
|||||||
Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
|
Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
|
||||||
Dictionary<int, bool> visited = new Dictionary<int, bool>();
|
Dictionary<int, bool> visited = new Dictionary<int, bool>();
|
||||||
List<List<int>> result = new List<List<int>>();
|
List<List<int>> result = new List<List<int>>();
|
||||||
|
|
||||||
// 构建图
|
// 构建图
|
||||||
foreach (var edge in arr)
|
foreach (var edge in arr)
|
||||||
{
|
{
|
||||||
@ -648,40 +648,34 @@ namespace FlightRouteV2
|
|||||||
return new_bVecs;
|
return new_bVecs;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从一组向量集合中 不重复的随机选择4个向量为一组 最多100组 组合成二维数组 如:[[1,2,3,4][5,6,7,8]...]
|
/// 从数组中删除指定索引处的元素
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vecs">坐标集和</param>
|
/// <typeparam name="T">数组元素类型</typeparam>
|
||||||
/// <returns>re空数组则代表不够4个坐标 </returns>
|
/// <param name="array">要操作的数组</param>
|
||||||
private static List<Vector3[]> RandomSel4Vec(Vector3[] vecs)
|
/// <param name="indicesToRemove">要删除的元素的索引列表</param>
|
||||||
|
/// <returns>删除元素后的新数组</returns>
|
||||||
|
private static T[] RemoveElementsAtIndices<T>(T[] array, List<int> indicesToRemove)
|
||||||
{
|
{
|
||||||
List<Vector3[]> result = new List<Vector3[]>();
|
// 检查索引是否有效
|
||||||
int len = vecs.Length;
|
if (indicesToRemove == null || indicesToRemove.Count == 0)
|
||||||
// 如果坐标数组少于4个,或者为空,则返回空列表
|
|
||||||
if (len < 4)
|
|
||||||
{
|
{
|
||||||
return result;
|
// 没有要删除的索引,返回原数组
|
||||||
|
return array;
|
||||||
}
|
}
|
||||||
// 确定最大可选择的组数,最多为100组
|
// 创建一个新数组,长度为原数组长度减去要删除的元素数量
|
||||||
int numGroups = Math.Min(len / 4, 100);
|
T[] newArray = new T[array.Length - indicesToRemove.Count];
|
||||||
List<Vector3> flattenedList = vecs.ToList();
|
int newIndex = 0;
|
||||||
Random random = new Random();
|
// 复制不包括指定索引的元素到新数组中
|
||||||
// 遍历每一组
|
for (int i = 0; i < array.Length; i++)
|
||||||
for (int i = 0; i < numGroups; i++)
|
|
||||||
{
|
{
|
||||||
List<Vector3> selectedGroup = new List<Vector3>();
|
if (!indicesToRemove.Contains(i))
|
||||||
|
|
||||||
// 随机选择4个不重复的坐标
|
|
||||||
for (int j = 0; j < 4; j++)
|
|
||||||
{
|
{
|
||||||
int index = random.Next(flattenedList.Count);
|
newArray[newIndex] = array[i];
|
||||||
selectedGroup.Add(flattenedList[index]);
|
newIndex++;
|
||||||
flattenedList.RemoveAt(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将选择的坐标组成的 List 转换为数组,并添加到结果中
|
|
||||||
result.Add(selectedGroup.ToArray());
|
|
||||||
}
|
}
|
||||||
return result;
|
// 返回新数组
|
||||||
|
return newArray;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置中间航点
|
/// 设置中间航点
|
||||||
@ -725,7 +719,7 @@ namespace FlightRouteV2
|
|||||||
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
|
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 叉积
|
/// 叉积 ps:法线向量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="v1">向量1</param>
|
/// <param name="v1">向量1</param>
|
||||||
/// <param name="v2">向量2</param>
|
/// <param name="v2">向量2</param>
|
||||||
@ -743,7 +737,7 @@ namespace FlightRouteV2
|
|||||||
/// <param name="v1">第一个向量</param>
|
/// <param name="v1">第一个向量</param>
|
||||||
/// <param name="v2">第二个向量</param>
|
/// <param name="v2">第二个向量</param>
|
||||||
/// <returns>角度</returns>
|
/// <returns>角度</returns>
|
||||||
public static double AngleBetween(Vector3 v1, Vector3 v2)
|
private static double AngleBetween(Vector3 v1, Vector3 v2)
|
||||||
{
|
{
|
||||||
// 计算点积
|
// 计算点积
|
||||||
double dotProduct = DotPro(v1, v2);
|
double dotProduct = DotPro(v1, v2);
|
||||||
@ -761,6 +755,77 @@ namespace FlightRouteV2
|
|||||||
return thetaDegrees;
|
return thetaDegrees;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 计算某个点到平面垂线与平面的交点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec1">平面上的点1</param>
|
||||||
|
/// <param name="vec2">平面上的点2</param>
|
||||||
|
/// <param name="vec3">平面上的点3</param>
|
||||||
|
/// <param name="vec4">被求点</param>
|
||||||
|
/// <returns>交点坐标</returns>
|
||||||
|
private static Vector3 CalculateIntersectionPoint(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
|
||||||
|
{
|
||||||
|
// 计算平面的法线向量
|
||||||
|
Vector3 normal = CrossPro(vec2 - vec1, vec3 - vec1);
|
||||||
|
normal.Normalize();
|
||||||
|
// 计算第4个点到平面的距离
|
||||||
|
double distance = DotPro(normal, vec1);
|
||||||
|
// 计算第4个点到平面的投影点坐标
|
||||||
|
double projection = DotPro(normal, vec4) - distance;
|
||||||
|
// 计算交点坐标
|
||||||
|
Vector3 intersectionPoint = vec4 - normal * projection;
|
||||||
|
return intersectionPoint;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 找到能组成平面的点的最大数量,并返回组成最大平面的点的索引。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vecs">Vector3 点的列表。</param>
|
||||||
|
/// <returns>组成最大平面的点的索引。</returns>
|
||||||
|
private static List<int> FindMaxPlaneIndices(Vector3[] vecs)
|
||||||
|
{
|
||||||
|
int maxPointsOnPlane = 0;
|
||||||
|
List<int> maxPointsIndices = new List<int>(); //记录返回值
|
||||||
|
int planeCou = vecs.Length; // 飞机总数
|
||||||
|
for (int i = 0; i < planeCou; i++)
|
||||||
|
{
|
||||||
|
for (int j = i + 1; j < planeCou; j++)
|
||||||
|
{
|
||||||
|
for (int k = j + 1; k < planeCou; k++)
|
||||||
|
{
|
||||||
|
int currentPointsOnPlane = 3; // 当前遍历的三个点肯定在同一平面上
|
||||||
|
|
||||||
|
for (int l = k + 1; l < planeCou; l++)
|
||||||
|
{
|
||||||
|
if (IsVecsOnPlane(vecs[i], vecs[j], vecs[k], vecs[l]))
|
||||||
|
{
|
||||||
|
// 当前的 l 也在同一平面上
|
||||||
|
currentPointsOnPlane++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前平面是否比之前找到的平面更大
|
||||||
|
if (currentPointsOnPlane > maxPointsOnPlane)
|
||||||
|
{
|
||||||
|
maxPointsOnPlane = currentPointsOnPlane;
|
||||||
|
maxPointsIndices.Clear();
|
||||||
|
maxPointsIndices.Add(i);
|
||||||
|
maxPointsIndices.Add(j);
|
||||||
|
maxPointsIndices.Add(k);
|
||||||
|
|
||||||
|
// 添加当前平面的 l 索引
|
||||||
|
for (int l = k + 1; l < planeCou; l++)
|
||||||
|
{
|
||||||
|
if (IsVecsOnPlane(vecs[i], vecs[j], vecs[k], vecs[l]))
|
||||||
|
{
|
||||||
|
maxPointsIndices.Add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxPointsIndices;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// 检查4个点是否在一个平面上
|
/// 检查4个点是否在一个平面上
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vector1">点1</param>
|
/// <param name="vector1">点1</param>
|
||||||
@ -768,14 +833,14 @@ namespace FlightRouteV2
|
|||||||
/// <param name="vector3">点3</param>
|
/// <param name="vector3">点3</param>
|
||||||
/// <param name="vector4">点4</param>
|
/// <param name="vector4">点4</param>
|
||||||
/// <returns>true在一个平面 false不在一个平面</returns>
|
/// <returns>true在一个平面 false不在一个平面</returns>
|
||||||
public static bool IsVecsOnPlane(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
|
private static bool IsVecsOnPlane(Vector3 vec1, Vector3 vec2, Vector3 vec3, Vector3 vec4)
|
||||||
{
|
{
|
||||||
//计算三个向量
|
//计算三个向量
|
||||||
Vector3 v1v2 = vec2 - vec1;
|
Vector3 v1v2 = vec2 - vec1;
|
||||||
Vector3 v1v3 = vec3 - vec1;
|
Vector3 v1v3 = vec3 - vec1;
|
||||||
Vector3 v1v4 = vec4 - vec1;
|
Vector3 v1v4 = vec4 - vec1;
|
||||||
//计算法线向量
|
//计算法线向量
|
||||||
Vector3 normal_vector = CrossPro(v1v2,v1v3);
|
Vector3 normal_vector = CrossPro(v1v2, v1v3);
|
||||||
//计算点到平面的距离
|
//计算点到平面的距离
|
||||||
double distance = DotPro(normal_vector, v1v4) / normal_vector.GetMag();
|
double distance = DotPro(normal_vector, v1v4) / normal_vector.GetMag();
|
||||||
//设置一个阈值,判断是否共面
|
//设置一个阈值,判断是否共面
|
||||||
@ -806,7 +871,7 @@ namespace FlightRouteV2
|
|||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从顶视图 判断点是否在两条内之间
|
/// 从顶视图 判断点是否在两条线内之间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="A">线段1端点</param>
|
/// <param name="A">线段1端点</param>
|
||||||
/// <param name="B">线段1端点</param>
|
/// <param name="B">线段1端点</param>
|
||||||
@ -817,7 +882,7 @@ namespace FlightRouteV2
|
|||||||
private static bool IsPointBetweenLines(Vector3 A, Vector3 B, Vector3 C, Vector3 D, Vector3 P)
|
private static bool IsPointBetweenLines(Vector3 A, Vector3 B, Vector3 C, Vector3 D, Vector3 P)
|
||||||
{
|
{
|
||||||
/// Y轴亚平 即顶视图
|
/// Y轴亚平 即顶视图
|
||||||
A = new Vector3(A.X,0,A.Z);
|
A = new Vector3(A.X, 0, A.Z);
|
||||||
B = new Vector3(B.X, 0, B.Z);
|
B = new Vector3(B.X, 0, B.Z);
|
||||||
C = new Vector3(C.X, 0, C.Z);
|
C = new Vector3(C.X, 0, C.Z);
|
||||||
D = new Vector3(D.X, 0, D.Z);
|
D = new Vector3(D.X, 0, D.Z);
|
||||||
@ -1140,7 +1205,7 @@ namespace FlightRouteV2
|
|||||||
/// <param name="aVecs">始点坐标集合</param>
|
/// <param name="aVecs">始点坐标集合</param>
|
||||||
/// <param name="bVecs">终点坐标集合</param>
|
/// <param name="bVecs">终点坐标集合</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static List<int[]> AirImitation(Vector3[] aVecs , List<Vector3> bVecs)
|
private static List<int[]> AirImitation(Vector3[] aVecs, List<Vector3> bVecs)
|
||||||
{
|
{
|
||||||
List<int[]> planesCollision = new List<int[]>(); //所有碰撞的组
|
List<int[]> planesCollision = new List<int[]>(); //所有碰撞的组
|
||||||
int planeCou = aVecs.Length; //获取飞机总数
|
int planeCou = aVecs.Length; //获取飞机总数
|
||||||
@ -1169,7 +1234,7 @@ namespace FlightRouteV2
|
|||||||
/// <param name="aVecs">始点坐标集合</param>
|
/// <param name="aVecs">始点坐标集合</param>
|
||||||
/// <param name="bVecs">终点坐标集合</param>
|
/// <param name="bVecs">终点坐标集合</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static List<int[]> AirImitation( List<Vector3> aVecs, Vector3[] bVecs)
|
private static List<int[]> AirImitation(List<Vector3> aVecs, Vector3[] bVecs)
|
||||||
{
|
{
|
||||||
List<int[]> planesCollision = new List<int[]>(); //所有碰撞的组
|
List<int[]> planesCollision = new List<int[]>(); //所有碰撞的组
|
||||||
int planeCou = aVecs.Count; //获取飞机总数
|
int planeCou = aVecs.Count; //获取飞机总数
|
||||||
@ -1302,15 +1367,43 @@ namespace FlightRouteV2
|
|||||||
/// <param name="aVecs">起始点坐标组</param>
|
/// <param name="aVecs">起始点坐标组</param>
|
||||||
/// <param name="bVecs">目标点坐标组</param>
|
/// <param name="bVecs">目标点坐标组</param>
|
||||||
/// <param name="StrPrint">日志输出 回调函数</param>
|
/// <param name="StrPrint">日志输出 回调函数</param>
|
||||||
|
/// <param name="isStaticSkip">静态跳过 true跳过即保持原地不动 false不跳过参与“最近和交换”计算</param>
|
||||||
|
/// <param name="staticThresholdSquare">静态距离判断 小于阈值判定为静态 注意是个平方值</param>
|
||||||
/// <param name="isSwap">交叉航线是否进行交换</param>
|
/// <param name="isSwap">交叉航线是否进行交换</param>
|
||||||
/// <param name="swapCount">交换次数</param>
|
/// <param name="swapCount">交换次数</param>
|
||||||
/// <param name="crossingLimit">交叉线路数量上限 ps:超过这个数量则不进行交换</param>
|
/// <param name="crossingLimit">交叉线路数量上限 ps:超过这个数量则不进行交换</param>
|
||||||
/// <returns>新的目标点</returns>
|
/// <returns>新的目标点</returns>
|
||||||
public static Vector3[] ContactABOut(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint, bool isSwap = true, int swapCount = 5, int crossingLimit = 6)
|
public static Vector3[] ContactABOut(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint,bool isStaticSkip = false, double staticThresholdSquare = 25 , bool isSwap = true, int swapCount = 5, int crossingLimit = 6)
|
||||||
{
|
{
|
||||||
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
StrPrint("-------智能选择路径计算,开始-------");
|
StrPrint("-------智能选择路径计算,开始-------");
|
||||||
int planeCou = aVecs.Length; // 飞机总数
|
int planeCou = aVecs.Length; // 飞机总数
|
||||||
|
List<int> staticAindex = new List<int>(); // a静态对应关系(ab两图同一位置)
|
||||||
|
List<int> staticBindex = new List<int>(); // b静态对应关系(ab两图同一位置)
|
||||||
|
Vector3[] new_aVecs = aVecs.ToArray(); //a图副本
|
||||||
|
Vector3[] new_bVecs = bVecs.ToArray(); //b图副本
|
||||||
|
///如果启动 静态航点跳过 把ab静态对应关系找出来 预存放到staticMatch
|
||||||
|
if (isStaticSkip)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < planeCou; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < planeCou; j++)
|
||||||
|
{
|
||||||
|
if (GageLengthSquare(aVecs[i], bVecs[j]) <= staticThresholdSquare)
|
||||||
|
{
|
||||||
|
staticAindex.Add(i);
|
||||||
|
staticBindex.Add(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//把静态的航点从列表里面清除
|
||||||
|
new_aVecs = RemoveElementsAtIndices(new_aVecs, staticAindex);
|
||||||
|
new_bVecs = RemoveElementsAtIndices(new_bVecs, staticBindex);
|
||||||
|
//刷新飞机总数 以下计算最近 和 交换航线时候 只有非静态飞机参与
|
||||||
|
planeCou = new_aVecs.Length;
|
||||||
|
}
|
||||||
|
|
||||||
List<int[]> match = new List<int[]>(); // ab对应关系
|
List<int[]> match = new List<int[]>(); // ab对应关系
|
||||||
///记录a b集合索引
|
///记录a b集合索引
|
||||||
List<int> aIndex = new List<int>();
|
List<int> aIndex = new List<int>();
|
||||||
@ -1330,8 +1423,8 @@ namespace FlightRouteV2
|
|||||||
List<Vector3> allVecs = new List<Vector3>();
|
List<Vector3> allVecs = new List<Vector3>();
|
||||||
for (int i = 0; i < remainCou; i++)
|
for (int i = 0; i < remainCou; i++)
|
||||||
{
|
{
|
||||||
allVecs.Add(aVecs[aIndex[i]]);
|
allVecs.Add(new_aVecs[aIndex[i]]);
|
||||||
allVecs.Add(bVecs[bIndex[i]]);
|
allVecs.Add(new_bVecs[bIndex[i]]);
|
||||||
}
|
}
|
||||||
Vector3 centerVec = GetPosCenter(allVecs);//重心点
|
Vector3 centerVec = GetPosCenter(allVecs);//重心点
|
||||||
// 遍历所有ab点距离重心点的距离
|
// 遍历所有ab点距离重心点的距离
|
||||||
@ -1339,8 +1432,8 @@ namespace FlightRouteV2
|
|||||||
double[] bLens = new double[remainCou];
|
double[] bLens = new double[remainCou];
|
||||||
for (int i = 0; i < remainCou; i++)
|
for (int i = 0; i < remainCou; i++)
|
||||||
{
|
{
|
||||||
aLens[i] = GageLengthSquare(aVecs[aIndex[i]], centerVec);
|
aLens[i] = GageLengthSquare(new_aVecs[aIndex[i]], centerVec);
|
||||||
bLens[i] = GageLengthSquare(bVecs[bIndex[i]], centerVec);
|
bLens[i] = GageLengthSquare(new_bVecs[bIndex[i]], centerVec);
|
||||||
}
|
}
|
||||||
// 找出ab集合最外层坐标的下标 即离重心点最远的点
|
// 找出ab集合最外层坐标的下标 即离重心点最远的点
|
||||||
int aMaxIndex = GetIndexOfMaxOrMin(aLens); // a集合到重心点最长的距离 数组的下标
|
int aMaxIndex = GetIndexOfMaxOrMin(aLens); // a集合到重心点最长的距离 数组的下标
|
||||||
@ -1350,7 +1443,7 @@ namespace FlightRouteV2
|
|||||||
double[] outAtoBLen = new double[remainCou];//最外层A点到 B集合所有点的距离
|
double[] outAtoBLen = new double[remainCou];//最外层A点到 B集合所有点的距离
|
||||||
for (int i = 0; i < remainCou; i++)
|
for (int i = 0; i < remainCou; i++)
|
||||||
{
|
{
|
||||||
outAtoBLen[i] = GageLengthSquare(aVecs[aIndex[aMaxIndex]], bVecs[bIndex[i]]);
|
outAtoBLen[i] = GageLengthSquare(new_aVecs[aIndex[aMaxIndex]], new_bVecs[bIndex[i]]);
|
||||||
}
|
}
|
||||||
int bMinIndex = GetIndexOfMaxOrMin(outAtoBLen, false);// 最短距离
|
int bMinIndex = GetIndexOfMaxOrMin(outAtoBLen, false);// 最短距离
|
||||||
match.Add(new int[] { aIndex[aMaxIndex], bIndex[bMinIndex] });// 映射到配对
|
match.Add(new int[] { aIndex[aMaxIndex], bIndex[bMinIndex] });// 映射到配对
|
||||||
@ -1362,7 +1455,7 @@ namespace FlightRouteV2
|
|||||||
double[] outBtoALen = new double[remainCou];//最外层B点到 A集合所有点的距离
|
double[] outBtoALen = new double[remainCou];//最外层B点到 A集合所有点的距离
|
||||||
for (int i = 0; i < remainCou; i++)
|
for (int i = 0; i < remainCou; i++)
|
||||||
{
|
{
|
||||||
outBtoALen[i] = GageLengthSquare(aVecs[aIndex[i]], bVecs[bIndex[bMaxIndex]]);
|
outBtoALen[i] = GageLengthSquare(new_aVecs[aIndex[i]], new_bVecs[bIndex[bMaxIndex]]);
|
||||||
}
|
}
|
||||||
int aMinIndex = GetIndexOfMaxOrMin(outBtoALen, false);// 最短距离
|
int aMinIndex = GetIndexOfMaxOrMin(outBtoALen, false);// 最短距离
|
||||||
match.Add(new int[] { aIndex[aMinIndex], bIndex[bMaxIndex] });// 映射到配对
|
match.Add(new int[] { aIndex[aMinIndex], bIndex[bMaxIndex] });// 映射到配对
|
||||||
@ -1370,89 +1463,105 @@ namespace FlightRouteV2
|
|||||||
bIndex.RemoveAt(bMaxIndex); // 删除已经配对的b集合 ID
|
bIndex.RemoveAt(bMaxIndex); // 删除已经配对的b集合 ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vector3[] new_bVecs = CreateNewBVecs(bVecs, match);// 按照映射 获取a 对应的 新的b集合
|
Vector3[] re_bVecs = CreateNewBVecs(new_bVecs, match);// 按照映射 获取a 对应的 新的b集合
|
||||||
if (!isSwap)
|
|
||||||
{
|
|
||||||
return new_bVecs;
|
|
||||||
}
|
|
||||||
///交叉 交换
|
///交叉 交换
|
||||||
for (int i = 0; i < swapCount; i++)
|
if (isSwap)
|
||||||
{
|
{
|
||||||
List<int[]> planesCollision = AirImitation(aVecs, new_bVecs);// 获取碰撞组
|
for (int i = 0; i < swapCount; i++)
|
||||||
List<List<int>> formatCollision = FindConnected(planesCollision);// 获取交叉序列 例如:[[0,2][0,3][3,4][5,6]] 结果[[0,2,3,4][5,6]]
|
|
||||||
List<List<int>> filteredCollision = formatCollision.Where(sublist => sublist.Count <= crossingLimit).ToList();// 过滤 只保留交叉数量小于等于crossingLimit的序列
|
|
||||||
if (filteredCollision.Count == 0) break;
|
|
||||||
///日志输出
|
|
||||||
string log = "";
|
|
||||||
foreach (List<int> item in filteredCollision)
|
|
||||||
{
|
{
|
||||||
log += "[";
|
List<int[]> planesCollision = AirImitation(new_aVecs, re_bVecs);// 获取碰撞组
|
||||||
foreach (int itemInt in item)
|
List<List<int>> formatCollision = FindConnected(planesCollision);// 获取交叉序列 例如:[[0,2][0,3][3,4][5,6]] 结果[[0,2,3,4][5,6]]
|
||||||
|
List<List<int>> filteredCollision = formatCollision.Where(sublist => sublist.Count <= crossingLimit).ToList();// 过滤 只保留交叉数量小于等于crossingLimit的序列
|
||||||
|
if (filteredCollision.Count == 0) break;
|
||||||
|
///日志输出
|
||||||
|
string log = "";
|
||||||
|
foreach (List<int> item in filteredCollision)
|
||||||
{
|
{
|
||||||
log += $"{itemInt},";
|
log += "[";
|
||||||
|
foreach (int itemInt in item)
|
||||||
|
{
|
||||||
|
log += $"{itemInt},";
|
||||||
|
}
|
||||||
|
log += "]";
|
||||||
}
|
}
|
||||||
log += "]";
|
StrPrint($"共迭代{swapCount}次交换,第{i}次。共{filteredCollision.Count}组,交换组为:{log}。");
|
||||||
}
|
/// 遍历所有交叉组 分组做交换
|
||||||
StrPrint($"共迭代{swapCount}次交换,第{i}次。共{filteredCollision.Count}组,交换组为:{log}。");
|
int cou = 0;
|
||||||
/// 遍历所有交叉组 分组做交换
|
foreach (List<int> swap_indices in filteredCollision)
|
||||||
int cou = 0;
|
|
||||||
foreach (List<int> swap_indices in filteredCollision)
|
|
||||||
{
|
|
||||||
cou++;
|
|
||||||
StrPrint($"进度:{cou}/{filteredCollision.Count}。交换组:[{string.Join(", ", swap_indices)}]。");
|
|
||||||
///交叉 生成所有排列
|
|
||||||
List<List<int>> all_permutations = Permutations(swap_indices);//所有排列组合
|
|
||||||
List<int> original = all_permutations[0];//原始排列
|
|
||||||
all_permutations.RemoveAt(0);//删掉第一个 既原始排列
|
|
||||||
/// 按所有的排列 互换航线 并检测出最佳的对应目标点
|
|
||||||
List<int> tempLen = new List<int>(); //记录最少碰撞的 排列
|
|
||||||
List<Vector3[]> tempNew_bVecsS = new List<Vector3[]>();//记录最少碰撞的 排列交换之后的目标坐标集
|
|
||||||
foreach (List<int> indices in all_permutations)
|
|
||||||
{
|
{
|
||||||
Vector3[] current_array = new Vector3[planeCou];
|
cou++;
|
||||||
Array.Copy(new_bVecs, current_array, planeCou);//复制一个new_bVecs 副本
|
StrPrint($"进度:{cou}/{filteredCollision.Count}。交换组:[{string.Join(", ", swap_indices)}]。");
|
||||||
for (int k = 0; k < indices.Count; k++)
|
///交叉 生成所有排列
|
||||||
|
List<List<int>> all_permutations = Permutations(swap_indices);//所有排列组合
|
||||||
|
List<int> original = all_permutations[0];//原始排列
|
||||||
|
all_permutations.RemoveAt(0);//删掉第一个 既原始排列
|
||||||
|
/// 按所有的排列 互换航线 并检测出最佳的对应目标点
|
||||||
|
List<int> tempLen = new List<int>(); //记录最少碰撞的 排列
|
||||||
|
List<Vector3[]> tempNew_bVecsS = new List<Vector3[]>();//记录最少碰撞的 排列交换之后的目标坐标集
|
||||||
|
foreach (List<int> indices in all_permutations)
|
||||||
{
|
{
|
||||||
current_array[original[k]] = new_bVecs[indices[k]];
|
Vector3[] current_array = new Vector3[planeCou];
|
||||||
}
|
Array.Copy(re_bVecs, current_array, planeCou);//复制一个re_bVecs 副本
|
||||||
///把最少碰撞的排列 录入到数组
|
for (int k = 0; k < indices.Count; k++)
|
||||||
int collisionsCou = (AirImitation(aVecs, current_array)).Count;//此排列的碰撞次数
|
{
|
||||||
if (tempLen.Count == 0 || tempLen[0] == collisionsCou)//如果第一次添加 或者 碰撞次数等于最少碰撞
|
current_array[original[k]] = re_bVecs[indices[k]];
|
||||||
{
|
}
|
||||||
///录入数组
|
///把最少碰撞的排列 录入到数组
|
||||||
tempLen.Add(collisionsCou);
|
int collisionsCou = (AirImitation(new_aVecs, current_array)).Count;//此排列的碰撞次数
|
||||||
tempNew_bVecsS.Add(current_array);
|
if (tempLen.Count == 0 || tempLen[0] == collisionsCou)//如果第一次添加 或者 碰撞次数等于最少碰撞
|
||||||
}
|
{
|
||||||
else if (tempLen[0] > collisionsCou)
|
///录入数组
|
||||||
{
|
tempLen.Add(collisionsCou);
|
||||||
/// 如果最小值 大于 当前碰撞次数,清空之前记录
|
tempNew_bVecsS.Add(current_array);
|
||||||
tempLen.Clear();
|
}
|
||||||
tempNew_bVecsS.Clear();
|
else if (tempLen[0] > collisionsCou)
|
||||||
///录入数组
|
{
|
||||||
tempLen.Add(collisionsCou);
|
/// 如果最小值 大于 当前碰撞次数,清空之前记录
|
||||||
tempNew_bVecsS.Add(current_array);
|
tempLen.Clear();
|
||||||
|
tempNew_bVecsS.Clear();
|
||||||
|
///录入数组
|
||||||
|
tempLen.Add(collisionsCou);
|
||||||
|
tempNew_bVecsS.Add(current_array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
re_bVecs = tempNew_bVecsS[GetRandomMinIndex(tempLen)];
|
||||||
}
|
}
|
||||||
new_bVecs = tempNew_bVecsS[GetRandomMinIndex(tempLen)];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
///静态飞机 赋值回 返回航点组 ps:航点赋值的位置是对应的a组的ID位置 映射到b组的位置
|
||||||
|
if (isStaticSkip)
|
||||||
|
{
|
||||||
|
planeCou = aVecs.Length;
|
||||||
|
List<Vector3> re_bVecsCopy = new List<Vector3>(re_bVecs);
|
||||||
|
List<Vector3> re_bVecsList = new List<Vector3>();
|
||||||
|
for (int i = 0; i < planeCou; i++)
|
||||||
|
{
|
||||||
|
if (staticAindex.IndexOf(i) != -1)
|
||||||
|
{
|
||||||
|
re_bVecsList.Add(aVecs[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
re_bVecsList.Add(re_bVecsCopy[0]);
|
||||||
|
re_bVecsCopy.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
re_bVecs = re_bVecsList.ToArray();
|
||||||
|
}
|
||||||
t = DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t;
|
t = DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t;
|
||||||
StrPrint($"用时:{t}秒");
|
StrPrint($"用时:{t}秒");
|
||||||
StrPrint($"-------智能选择路径计算,结束-------");
|
StrPrint($"-------智能选择路径计算,结束-------");
|
||||||
return new_bVecs;
|
return re_bVecs;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 智能错层
|
/// 智能错层
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="aVecs">起始坐标集合</param>
|
/// <param name="aVecs">起始坐标集合</param>
|
||||||
/// <param name="bVecs">终点做标集合</param>
|
/// <param name="bVecs">终点做标集合</param>
|
||||||
/// <param name="aName">起始坐标航点名称</param>
|
|
||||||
/// <param name="bName">终点坐标航点名称</param>
|
|
||||||
/// <param name="StrPrint">日志输出 回调函数</param>
|
/// <param name="StrPrint">日志输出 回调函数</param>
|
||||||
/// <param name="layHight">错层层高</param>
|
/// <param name="layHight">错层层高</param>
|
||||||
/// <returns>返回一个二维向量坐标集合 middle[0]是第一个中间航点 middle[1]是第二个中间航点 返回空数组则代表两个图形不在一个平面上或者不够4个点</returns>
|
/// <returns>返回一个二维向量坐标集合 middle[0]是第一个中间航点 middle[1]是第二个中间航点 返回空数组则代表两个图形不在一个平面上或者不够4个点</returns>
|
||||||
public static List<List<Vector3>> CollisionLayer(Vector3[] aVecs, Vector3[] bVecs,string aName,string bName ,SomeCalculateWay StrPrint, double layHight = 185)
|
public static List<List<Vector3>> CollisionLayer(Vector3[] aVecs, Vector3[] bVecs,SomeCalculateWay StrPrint, double layHight = 300)
|
||||||
{
|
{
|
||||||
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
StrPrint("-------错层,开始-------");
|
StrPrint("-------错层,开始-------");
|
||||||
@ -1467,102 +1576,73 @@ namespace FlightRouteV2
|
|||||||
}
|
}
|
||||||
//获取飞机总数
|
//获取飞机总数
|
||||||
int planeCou = aVecs.Length;
|
int planeCou = aVecs.Length;
|
||||||
if (planeCou < 2)//至少不少于2架飞机 才开始错层
|
|
||||||
|
Vector3[] new_aVecs = aVecs.ToArray(); //a图副本
|
||||||
|
Vector3[] new_bVecs = bVecs.ToArray(); //b图副本
|
||||||
|
|
||||||
|
///把所有点压在 主面“共面”上
|
||||||
|
List<int> maxVecsOfCoplane = FindMaxPlaneIndices(aVecs);// 找出A图共面最多点的索引
|
||||||
|
StrPrint("正在进行“共面”检测,需要一些时间请耐心等待。。。");
|
||||||
|
if (maxVecsOfCoplane.Count < 4) //a图至少要有4个点 共面
|
||||||
{
|
{
|
||||||
StrPrint("图案至少要两个点阵!");
|
StrPrint("a图案至少有4个点以上共面,否则不可执行错层处理");
|
||||||
|
StrPrint($"-------错层结束-------");
|
||||||
return re;
|
return re;
|
||||||
}
|
}
|
||||||
|
///共面上取三个点
|
||||||
|
Vector3 vec0 = new_aVecs[maxVecsOfCoplane[0]];
|
||||||
|
Vector3 vec1 = new_aVecs[maxVecsOfCoplane[1]];
|
||||||
|
Vector3 vec2 = new_aVecs[maxVecsOfCoplane[2]];
|
||||||
|
///遍历 把a图和b图点压到 “共面”上
|
||||||
|
for (int i = 0; i < planeCou; i++)
|
||||||
|
{
|
||||||
|
if (!(maxVecsOfCoplane.Contains(i))) //除去在共面内的面
|
||||||
|
{
|
||||||
|
new_aVecs[i] = CalculateIntersectionPoint(vec0, vec1, vec2, new_aVecs[i]); //压平到共面上
|
||||||
|
}
|
||||||
|
new_bVecs[i] = CalculateIntersectionPoint(vec0, vec1, vec2, new_bVecs[i]); //压平到共面上
|
||||||
|
}
|
||||||
|
|
||||||
///从ab图案中取最外层3个点 确定一个面 ps:方便后续叉积算法线标量
|
///计算法线向量
|
||||||
Vector3 vec0 = new Vector3(0, 0, 0); //记录最外圈一个坐标
|
|
||||||
Vector3 vec1 = new Vector3(0, 0, 0); //记录离最外圈坐标最远的一个点坐标
|
|
||||||
Vector3 vec2 = new Vector3(0, 0, 0); //最外圈距离 和最远距离 之和最远的一个点
|
|
||||||
// 求重心
|
|
||||||
List<Vector3> allVecs = new List<Vector3>();
|
|
||||||
for (int i = 0; i < planeCou; i++)
|
|
||||||
{
|
|
||||||
allVecs.Add(aVecs[i]);
|
|
||||||
allVecs.Add(bVecs[i]);
|
|
||||||
}
|
|
||||||
Vector3 centerVec = GetPosCenter(allVecs);//重心点
|
|
||||||
// 遍历所有ab点
|
|
||||||
double tempLong = 0;
|
|
||||||
double currentLong;
|
|
||||||
for (int i = 0; i < planeCou * 2; i++) //取最外圈一个坐标
|
|
||||||
{
|
|
||||||
currentLong = GageLength(allVecs[i], centerVec);
|
|
||||||
if (tempLong < currentLong)
|
|
||||||
{
|
|
||||||
vec0 = allVecs[i];
|
|
||||||
tempLong = currentLong;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempLong = 0;
|
|
||||||
for (int i = 0; i < planeCou * 2; i++) //取最外圈点
|
|
||||||
{
|
|
||||||
currentLong = GageLength(allVecs[i], vec0);
|
|
||||||
if (tempLong < currentLong)
|
|
||||||
{
|
|
||||||
vec1 = allVecs[i];
|
|
||||||
tempLong = currentLong;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempLong = 0;
|
|
||||||
for (int i = 0; i < planeCou * 2; i++) //取最外圈点
|
|
||||||
{
|
|
||||||
currentLong =(GageLength(allVecs[i], vec0) + GageLength(allVecs[i], vec1));
|
|
||||||
if (tempLong < currentLong)
|
|
||||||
{
|
|
||||||
vec2 = allVecs[i];
|
|
||||||
tempLong = currentLong;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
///遍历两个图形所有点 是否在一个平面上
|
|
||||||
string aNoPlaneSN= "";//记录a图案所有不在一个平面上的点
|
|
||||||
string bNoPlaneSN = "";//记录b图案所有不在一个平面上的点
|
|
||||||
for (int i = 0; i < planeCou; i++)
|
|
||||||
{
|
|
||||||
if (!IsVecsOnPlane(vec0, vec1, vec2, aVecs[i])) aNoPlaneSN += $"{i+1},";
|
|
||||||
if (!IsVecsOnPlane(vec0, vec1, vec2, bVecs[i])) bNoPlaneSN += $"{i+1},";
|
|
||||||
}
|
|
||||||
if (aNoPlaneSN != "" || bNoPlaneSN != "")
|
|
||||||
{
|
|
||||||
if (aNoPlaneSN != "") StrPrint($"“{aName}”:{aNoPlaneSN}号飞机 ,不在一个平面,故不能做搓层处理!");
|
|
||||||
if (bNoPlaneSN != "") StrPrint($"“{bName}”:{bNoPlaneSN}号飞机 ,不在一个平面,故不能做搓层处理!");
|
|
||||||
StrPrint($"-------错层,结束-------");
|
|
||||||
return re;//两个图形不在一个平面上 返回 空数组
|
|
||||||
}
|
|
||||||
///检查完毕后
|
|
||||||
//计算法线向量
|
|
||||||
Vector3 side1 = vec1 - vec0;
|
Vector3 side1 = vec1 - vec0;
|
||||||
Vector3 side2 = vec2 - vec0;
|
Vector3 side2 = vec2 - vec0;
|
||||||
Vector3 normal = CrossPro(side1, side2);
|
Vector3 normal = CrossPro(side1, side2);
|
||||||
Vector3 normalScalar = normal.NormalizEd();//法线标量
|
Vector3 normalScalar = normal.NormalizEd();//法线标量
|
||||||
//开始错层
|
///开始错层
|
||||||
for (int i = 0; i < planeCou; i++)
|
for (int i = 0; i < planeCou; i++)
|
||||||
{
|
{
|
||||||
int shiftCou = 1; //记录循环次数 即层数
|
int shiftCou = 1; //记录循环次数 即层数
|
||||||
Vector3 aOrigin = aVecs[i]; //原点位置
|
Vector3 aOrigin = new_aVecs[i]; //原点位置
|
||||||
Vector3 bOrigin = bVecs[i]; //原点位置
|
Vector3 bOrigin = new_bVecs[i]; //原点位置
|
||||||
while (OnlyImitation(i, aVecs, bVecs))
|
while (OnlyImitation(i, new_aVecs, new_bVecs))
|
||||||
{
|
{
|
||||||
Vector3 shiftVec = normalScalar * ((shiftCou + 1) / 2 * layHight);
|
Vector3 shiftVec = normalScalar * ((shiftCou + 1) / 2 * layHight);
|
||||||
if (shiftCou % 2 == 1)
|
if (shiftCou % 2 == 1)
|
||||||
{
|
{
|
||||||
aVecs[i] = aOrigin + shiftVec;
|
new_aVecs[i] = aOrigin + shiftVec;
|
||||||
bVecs[i] = bOrigin + shiftVec;
|
new_bVecs[i] = bOrigin + shiftVec;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aVecs[i] = aOrigin - shiftVec;
|
new_aVecs[i] = aOrigin - shiftVec;
|
||||||
bVecs[i] = bOrigin - shiftVec;
|
new_bVecs[i] = bOrigin - shiftVec;
|
||||||
}
|
}
|
||||||
shiftCou += 1;
|
shiftCou += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
re.Add(aVecs.ToList());
|
///计算碰撞
|
||||||
re.Add(bVecs.ToList());
|
planesCollision = AirImitation(aVecs, new_aVecs).Concat(AirImitation(new_aVecs, new_bVecs)).ToList(); //获取碰撞组
|
||||||
StrPrint($"错层成功");
|
planesCollision = planesCollision.Concat(AirImitation(new_bVecs, bVecs)).ToList();
|
||||||
|
if (planesCollision.Count == 0)
|
||||||
|
{
|
||||||
|
re.Add(new_aVecs.ToList());
|
||||||
|
re.Add(new_bVecs.ToList());
|
||||||
|
StrPrint($"错层成功");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StrPrint($"检测有碰撞,错层失败");
|
||||||
|
}
|
||||||
t = DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t;
|
t = DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t;
|
||||||
StrPrint($"用时:{t}秒");
|
StrPrint($"用时:{t}秒");
|
||||||
StrPrint($"-------错层结束-------");
|
StrPrint($"-------错层结束-------");
|
||||||
@ -1574,10 +1654,12 @@ namespace FlightRouteV2
|
|||||||
/// <param name="aVecs">起始坐标集合</param>
|
/// <param name="aVecs">起始坐标集合</param>
|
||||||
/// <param name="bVecs">终点做标集合</param>
|
/// <param name="bVecs">终点做标集合</param>
|
||||||
/// <param name="StrPrint">日志输出 回调函数</param>
|
/// <param name="StrPrint">日志输出 回调函数</param>
|
||||||
/// <param name="GetVal">日志输出 回调函数</param>
|
/// <param name="GetVal">进度日志输出 回调函数</param>
|
||||||
|
/// <param name="cancellationToken">函数“取消执行”ps:new一个CancellationTokenSource类型 把实例.Token属性传进来,函数外部用实例.Cancel()函数控制实参值(bool)</param>
|
||||||
/// <param name="isPass">out参数 返回true不碰撞程序直接返回 false有碰撞程序向下执行</param>
|
/// <param name="isPass">out参数 返回true不碰撞程序直接返回 false有碰撞程序向下执行</param>
|
||||||
|
/// <param name="mappingId">飞机真实序号的映射关系</param>
|
||||||
/// <returns>返回一个二维数组 返回值长度0没有检测到碰撞或绕行失败 长度1为一个中间航点 长度为3为三个中间航点顺序(前中后)</returns>
|
/// <returns>返回一个二维数组 返回值长度0没有检测到碰撞或绕行失败 长度1为一个中间航点 长度为3为三个中间航点顺序(前中后)</returns>
|
||||||
public static List<List<Vector3>> ABypassB(Vector3[] aVecs, Vector3[] bVecs,SomeCalculateWay StrPrint, Schedule GetVal, CancellationToken cancellationToken, out bool isPass, List<int> mappingId = null)
|
public static List<List<Vector3>> ABypassB(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint, Schedule GetVal, CancellationToken cancellationToken, out bool isPass, List<int> mappingId = null)
|
||||||
{
|
{
|
||||||
isPass = false;
|
isPass = false;
|
||||||
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||||
@ -1618,14 +1700,14 @@ namespace FlightRouteV2
|
|||||||
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
||||||
{
|
{
|
||||||
StrPrint("-------3D绕行操作被取消-------");
|
StrPrint("-------3D绕行操作被取消-------");
|
||||||
return re; // 退出函数
|
return null; // 退出函数
|
||||||
}
|
}
|
||||||
int progress = 0;//进度
|
int progress = 0;//进度
|
||||||
foreach (int i in collisionGroup)//开始绕碰撞组
|
foreach (int i in collisionGroup)//开始绕碰撞组
|
||||||
{
|
{
|
||||||
progress++;
|
progress++;
|
||||||
GetVal(progress/collisionGroup.Count*100);
|
GetVal(progress / collisionGroup.Count * 100);
|
||||||
List<Vector3> grv = GetRingVec(aVecs[i], bVecs[i], 0.5, 5, 4, 1500);//中间可绕行航点列表
|
List<Vector3> grv = GetRingVec(aVecs[i], bVecs[i], 0.5, 5, 4, 1500, 300);//中间可绕行航点列表
|
||||||
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{grv.Count}次");
|
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{grv.Count}次");
|
||||||
foreach (Vector3 v in grv)
|
foreach (Vector3 v in grv)
|
||||||
{
|
{
|
||||||
@ -1680,7 +1762,7 @@ namespace FlightRouteV2
|
|||||||
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
||||||
{
|
{
|
||||||
StrPrint("-------3D绕行操作被取消-------");
|
StrPrint("-------3D绕行操作被取消-------");
|
||||||
return re; // 退出函数
|
return null; // 退出函数
|
||||||
}
|
}
|
||||||
int progress = 0;//进度
|
int progress = 0;//进度
|
||||||
foreach (int i in collisionGroup)//开始绕碰撞组
|
foreach (int i in collisionGroup)//开始绕碰撞组
|
||||||
@ -1688,9 +1770,9 @@ namespace FlightRouteV2
|
|||||||
progress++;
|
progress++;
|
||||||
GetVal(progress / collisionGroup.Count * 100);
|
GetVal(progress / collisionGroup.Count * 100);
|
||||||
//StrPrint($"迭代{c}次{i}号绕行");
|
//StrPrint($"迭代{c}次{i}号绕行");
|
||||||
List<Vector3> sgrv1 = GetRingVec(aVecs[i], bVecs[i], 0, 30, 10,600);//中间可绕行航点列表
|
List<Vector3> sgrv1 = GetRingVec(aVecs[i], bVecs[i], 0, 30, 10, 600, 300);//中间可绕行航点列表
|
||||||
sgrv1.Insert(0, secondMiddleVecsOne[i]);
|
sgrv1.Insert(0, secondMiddleVecsOne[i]);
|
||||||
List<Vector3> sgrv2 = GetRingVec(aVecs[i], bVecs[i], 1, 30, 10,600);//中间可绕行航点列表
|
List<Vector3> sgrv2 = GetRingVec(aVecs[i], bVecs[i], 1, 30, 10, 600, 300);//中间可绕行航点列表
|
||||||
sgrv2.Insert(0, secondMiddleVecsTwo[i]);
|
sgrv2.Insert(0, secondMiddleVecsTwo[i]);
|
||||||
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{sgrv1.Count * sgrv2.Count}次");
|
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{sgrv1.Count * sgrv2.Count}次");
|
||||||
foreach (Vector3 v1 in sgrv1)
|
foreach (Vector3 v1 in sgrv1)
|
||||||
@ -1753,7 +1835,7 @@ namespace FlightRouteV2
|
|||||||
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
if (cancellationToken.IsCancellationRequested)//外部法取消指令
|
||||||
{
|
{
|
||||||
StrPrint("-------3D绕行操作被取消-------");
|
StrPrint("-------3D绕行操作被取消-------");
|
||||||
return re; // 退出函数
|
return null; // 退出函数
|
||||||
}
|
}
|
||||||
int progress = 0;//进度
|
int progress = 0;//进度
|
||||||
foreach (int i in collisionGroup)//开始绕碰撞组
|
foreach (int i in collisionGroup)//开始绕碰撞组
|
||||||
@ -1761,11 +1843,11 @@ namespace FlightRouteV2
|
|||||||
GetVal(progress / collisionGroup.Count * 100);
|
GetVal(progress / collisionGroup.Count * 100);
|
||||||
progress++;
|
progress++;
|
||||||
//StrPrint($"迭代{c}次{i}号绕行");
|
//StrPrint($"迭代{c}次{i}号绕行");
|
||||||
List<Vector3> sgrv1 = GetRingVec(aVecs[i], bVecs[i], 0, 100, 10, 600);//中间可绕行航点列表
|
List<Vector3> sgrv1 = GetRingVec(aVecs[i], bVecs[i], 0, 100, 10, 600, 300);//中间可绕行航点列表
|
||||||
sgrv1.Insert(0, secondMiddleVecsOne[i]);
|
sgrv1.Insert(0, secondMiddleVecsOne[i]);
|
||||||
List<Vector3> sgrv2 = GetRingVec(aVecs[i], bVecs[i], 1, 100, 10, 600);//中间可绕行航点列表
|
List<Vector3> sgrv2 = GetRingVec(aVecs[i], bVecs[i], 1, 100, 10, 600, 300);//中间可绕行航点列表
|
||||||
sgrv2.Insert(0, secondMiddleVecsTwo[i]);
|
sgrv2.Insert(0, secondMiddleVecsTwo[i]);
|
||||||
List<Vector3> grv = GetRingVec(secondMiddleVecsOne[i], secondMiddleVecsTwo[i], 0.5, 80, 4, 1500);//中间可绕行航点列表
|
List<Vector3> grv = GetRingVec(secondMiddleVecsOne[i], secondMiddleVecsTwo[i], 0.5, 80, 4, 1500, 300);//中间可绕行航点列表
|
||||||
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{sgrv1.Count * sgrv2.Count * grv.Count}次");
|
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{sgrv1.Count * sgrv2.Count * grv.Count}次");
|
||||||
foreach (Vector3 vm in grv)
|
foreach (Vector3 vm in grv)
|
||||||
{
|
{
|
||||||
@ -1776,7 +1858,7 @@ namespace FlightRouteV2
|
|||||||
foreach (Vector3 v2 in sgrv2)
|
foreach (Vector3 v2 in sgrv2)
|
||||||
{
|
{
|
||||||
secondMiddleVecsTwo[i] = v2;
|
secondMiddleVecsTwo[i] = v2;
|
||||||
if (!OnlyImitation(i, aVecs, secondMiddleVecsOne) && !OnlyImitation(i, secondMiddleVecsOne, thirdMiddleVecs ) && !OnlyImitation(i, thirdMiddleVecs, secondMiddleVecsTwo) && !OnlyImitation(i, secondMiddleVecsTwo, bVecs))
|
if (!OnlyImitation(i, aVecs, secondMiddleVecsOne) && !OnlyImitation(i, secondMiddleVecsOne, thirdMiddleVecs) && !OnlyImitation(i, thirdMiddleVecs, secondMiddleVecsTwo) && !OnlyImitation(i, secondMiddleVecsTwo, bVecs))
|
||||||
{
|
{
|
||||||
isPassMark = true;
|
isPassMark = true;
|
||||||
break;
|
break;
|
||||||
@ -1867,7 +1949,7 @@ namespace FlightRouteV2
|
|||||||
/// <param name="layHight">偏移层高</param>
|
/// <param name="layHight">偏移层高</param>
|
||||||
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
|
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
|
||||||
/// <returns>矩阵</returns>
|
/// <returns>矩阵</returns>
|
||||||
private static Matrix GetBasisMatrix(Vector3 aVec, Vector3 bVec, double middleProportion, int offCount, double layHight,string direction)
|
private static Matrix GetBasisMatrix(Vector3 aVec, Vector3 bVec, double middleProportion, int offCount, double layHight, string direction)
|
||||||
{
|
{
|
||||||
/// 计算前向向量 k帽
|
/// 计算前向向量 k帽
|
||||||
Vector3 k_hat = (bVec - aVec).NormalizEd();
|
Vector3 k_hat = (bVec - aVec).NormalizEd();
|
||||||
@ -1892,7 +1974,7 @@ namespace FlightRouteV2
|
|||||||
{
|
{
|
||||||
offShift = middleProportion + offCount * layHight / length;
|
offShift = middleProportion + offCount * layHight / length;
|
||||||
}
|
}
|
||||||
else if(direction == "backward")
|
else if (direction == "backward")
|
||||||
{
|
{
|
||||||
offShift = middleProportion - offCount * layHight / length;
|
offShift = middleProportion - offCount * layHight / length;
|
||||||
}
|
}
|
||||||
@ -1929,17 +2011,20 @@ namespace FlightRouteV2
|
|||||||
/// <param name="maxPaunchRadius">设定圆盘半径 的最大值 单位是厘米</param>
|
/// <param name="maxPaunchRadius">设定圆盘半径 的最大值 单位是厘米</param>
|
||||||
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
|
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
|
||||||
/// <returns>绕行航点列表</returns>
|
/// <returns>绕行航点列表</returns>
|
||||||
public static List<Vector3> GetRingVec(Vector3 aVec, Vector3 bVec, double middleProportion, double transfer, double paunch,double maxPaunchRadius, string direction = "retrun")
|
public static List<Vector3> GetRingVec(Vector3 aVec, Vector3 bVec, double middleProportion, double transfer, double paunch, double maxPaunchRadius, double minPaunchRadius, string direction = "retrun")
|
||||||
{
|
{
|
||||||
List<Vector3> ringVec = new List<Vector3>(); //记录所有绕行中间航点坐标
|
List<Vector3> ringVec = new List<Vector3>(); //记录所有绕行中间航点坐标
|
||||||
/// 根据a到b的长度 算出中间绕行几圈
|
/// 根据a到b的长度 算出中间绕行几圈
|
||||||
double discRadius = GageLength(aVec, bVec) / paunch;//圆盘半径
|
double discRadius = GageLength(aVec, bVec) / paunch;//圆盘半径
|
||||||
if (discRadius > maxPaunchRadius)
|
if (discRadius > maxPaunchRadius)
|
||||||
{
|
{
|
||||||
discRadius = maxPaunchRadius;//设定圆盘不经不超过最大值
|
discRadius = maxPaunchRadius;//设定圆盘直径上限
|
||||||
}
|
}
|
||||||
int ringCou = (int)Math.Ceiling(discRadius / transfer ); //算层数和圈数 ps:层的厚度 和 圈的直径 为 paunch/航线长度
|
if (discRadius < minPaunchRadius)
|
||||||
if (ringCou < 2) ringCou = 2; //最少两圈 两层
|
{
|
||||||
|
discRadius = minPaunchRadius;//设定圆盘直径下限
|
||||||
|
}
|
||||||
|
int ringCou = (int)Math.Ceiling(discRadius / transfer); //算层数和圈数 ps:层的厚度 和 圈的直径 为 paunch/航线长度
|
||||||
/// 不是单圈的话 设置层数跟圈数相等
|
/// 不是单圈的话 设置层数跟圈数相等
|
||||||
int layCou = ringCou;
|
int layCou = ringCou;
|
||||||
if (singleCircle) layCou = 1;
|
if (singleCircle) layCou = 1;
|
||||||
@ -1971,30 +2056,48 @@ namespace FlightRouteV2
|
|||||||
/// <param name="aVecs">平面图案坐标组</param>
|
/// <param name="aVecs">平面图案坐标组</param>
|
||||||
/// <param name="bVecs">回归矩阵坐标组</param>
|
/// <param name="bVecs">回归矩阵坐标组</param>
|
||||||
/// <param name="strPrint">日志输出 回调函数</param>
|
/// <param name="strPrint">日志输出 回调函数</param>
|
||||||
|
/// <param name="pullingDistance">拉散层距</param>
|
||||||
/// <returns>拉散图案的坐标组</returns>
|
/// <returns>拉散图案的坐标组</returns>
|
||||||
public static Vector3[] NormalPull(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint)
|
public static Vector3[] NormalPull(Vector3[] aVecs, Vector3[] bVecs, SomeCalculateWay StrPrint,double pullingDistance = 300)
|
||||||
{
|
{
|
||||||
Vector3[] new_aVecs = aVecs.ToArray();
|
Vector3[] new_aVecs = aVecs.ToArray(); //a图副本
|
||||||
Vector3[] new_bVecs = bVecs.ToArray();
|
Vector3[] new_bVecs = bVecs.ToArray(); //矩阵副本
|
||||||
int planeCou = new_aVecs.Length; //获取飞机总数
|
int planeCou = new_aVecs.Length; //获取飞机总数
|
||||||
|
///判断a图是不是平面
|
||||||
|
if (!(planeCou == FindMaxPlaneIndices(aVecs).Count))
|
||||||
|
{
|
||||||
|
StrPrint("-------前图航点非平面图形,故不能做拉散图案操作-------");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
///a图b图 中心
|
///a图b图 中心
|
||||||
Vector3 aCenterPos = GetPosCenter(new_aVecs, false);
|
Vector3 aCenterPos = GetPosCenter(new_aVecs, false);
|
||||||
Vector3 bCenterPos = GetPosCenter(new_bVecs, false);
|
|
||||||
///判断bVec 矩阵的数量长宽
|
///判断bVec 矩阵的数量长宽
|
||||||
for (int i = 0; i < planeCou; i++)//把矩阵高度压平
|
for (int i = 0; i < planeCou; i++)//把矩阵高度压平
|
||||||
{
|
{
|
||||||
new_bVecs[i] = new Vector3(new_bVecs[i].X, 0, new_bVecs[i].Z);
|
new_bVecs[i] = new Vector3(new_bVecs[i].X, 0, new_bVecs[i].Z);
|
||||||
}
|
}
|
||||||
int row = 1 ;
|
int row = 1;
|
||||||
for (int i = 0; i < planeCou-2; i++)
|
for (int i = 0; i < planeCou - 2; i++)
|
||||||
{
|
{
|
||||||
if (!(IsVecsOnLine(new_bVecs[i], new_bVecs[i + 1], new_bVecs[i + 2])))
|
if (!(IsVecsOnLine(new_bVecs[i], new_bVecs[i + 1], new_bVecs[i + 2])))
|
||||||
{
|
{
|
||||||
row = i+2;//列
|
row = i + 2;//列
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int ran = (int)Math.Ceiling((double)planeCou/(double)row);//行
|
int ran = (int)Math.Ceiling((double)planeCou / (double)row);//行
|
||||||
|
StrPrint($"{ran}行{row}列");
|
||||||
|
if (ran > 2)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ran - 2; i++)
|
||||||
|
{
|
||||||
|
if (!(IsVecsOnLine(new_bVecs[i * row], new_bVecs[(i + 1) * row], new_bVecs[(i + 2) * row])))
|
||||||
|
{
|
||||||
|
StrPrint("-------降落航点非常规矩阵,故不能做拉散图案操作-------");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
///计算a图的法线标量
|
///计算a图的法线标量
|
||||||
Vector3 side1 = new_aVecs[1] - new_aVecs[0];
|
Vector3 side1 = new_aVecs[1] - new_aVecs[0];
|
||||||
Vector3 side2 = new_aVecs[2] - new_aVecs[0];
|
Vector3 side2 = new_aVecs[2] - new_aVecs[0];
|
||||||
@ -2014,20 +2117,20 @@ namespace FlightRouteV2
|
|||||||
for (int i = 0; i < ran; i++)
|
for (int i = 0; i < ran; i++)
|
||||||
{
|
{
|
||||||
int cou = i * row + k;
|
int cou = i * row + k;
|
||||||
if (cou > planeCou) break;// 溢出跳出
|
if (cou >= planeCou) break;// 溢出跳出
|
||||||
///判断图在矩阵的左方 还是右方
|
///判断图在矩阵的左方 还是右方
|
||||||
if (GageLength(aCenterPos, new_bVecs[0]) > GageLength(aCenterPos, new_bVecs[row - 1]))
|
if (GageLength(aCenterPos, new_bVecs[0]) > GageLength(aCenterPos, new_bVecs[row - 1]))
|
||||||
{
|
{
|
||||||
new_aVecs[cou] -= normalScalar * (row - k) * 300;//左方
|
new_aVecs[cou] -= normalScalar * (row - k) * pullingDistance;//左方
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_aVecs[cou] += normalScalar * k * 300;//右方
|
new_aVecs[cou] += normalScalar * k * pullingDistance;//右方
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
///判断a图的中心点 是否在矩阵内部 在矩阵内部 做一个a b两组中心点对其 ps:相当于朝两边拉散
|
///判断a图的中心点 是否在矩阵内部 在矩阵内部 做一个a b两组中心点对其 ps:相当于朝两边拉散
|
||||||
if (IsPointBetweenLines(new_bVecs[(int)Math.Ceiling(((double)row/5))-1], new_bVecs[(int)Math.Ceiling(((double)row / 5)) - 1+row], new_bVecs[row-((int)Math.Ceiling(((double)row / 5)) - 1)], new_bVecs[(row - ((int)Math.Ceiling(((double)row / 5)) - 1))+row], aCenterPos))
|
if (IsPointBetweenLines(new_bVecs[(int)Math.Ceiling(((double)row / 5)) - 1], new_bVecs[(int)Math.Ceiling(((double)row / 5)) - 1 + row], new_bVecs[row - ((int)Math.Ceiling(((double)row / 5)) - 1)], new_bVecs[(row - ((int)Math.Ceiling(((double)row / 5)) - 1)) + row], aCenterPos))
|
||||||
{
|
{
|
||||||
if (GageLength(new_aVecs[0], aVecs[0]) > GageLength(new_aVecs[planeCou - 1], aVecs[planeCou - 1]))//判断最大偏移量 是第一排 还是最后一排
|
if (GageLength(new_aVecs[0], aVecs[0]) > GageLength(new_aVecs[planeCou - 1], aVecs[planeCou - 1]))//判断最大偏移量 是第一排 还是最后一排
|
||||||
{
|
{
|
||||||
@ -2056,15 +2159,16 @@ namespace FlightRouteV2
|
|||||||
for (int i = 0; i < row; i++)
|
for (int i = 0; i < row; i++)
|
||||||
{
|
{
|
||||||
int cou = k * row + i;
|
int cou = k * row + i;
|
||||||
if (cou > planeCou) break;// 溢出跳出
|
//StrPrint($"{cou}");
|
||||||
|
if (cou >= planeCou) break;// 溢出跳出
|
||||||
///判断图在矩阵的上方 还是下方
|
///判断图在矩阵的上方 还是下方
|
||||||
if (GageLength(aCenterPos, new_bVecs[0]) > GageLength(aCenterPos, new_bVecs[row * (ran - 1)]))
|
if (GageLength(aCenterPos, new_bVecs[0]) > GageLength(aCenterPos, new_bVecs[row * (ran - 1)]))
|
||||||
{
|
{
|
||||||
new_aVecs[cou] -= normalScalar * (ran - k) * 300;//上方
|
new_aVecs[cou] -= normalScalar * (ran - k) * pullingDistance;//上方
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_aVecs[cou] += normalScalar * k * 300;//下方
|
new_aVecs[cou] += normalScalar * k * pullingDistance;//下方
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -16,15 +16,18 @@
|
|||||||
<Label Content="顶视图" FontSize="14" Background="#556b6b6b" Foreground="#FFDCDCDC" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0" />
|
<Label Content="顶视图" FontSize="14" Background="#556b6b6b" Foreground="#FFDCDCDC" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0" />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid Name="MainMenu" Width="220" Height="800" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top">
|
<Grid Name="MainMenu" Width="220" Height="800" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||||
<Button Content="导入航点" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,0,0,0" Click="ImportFcgm_Click"/>
|
<Button Content="导入航点" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,0,0,0" Click="ImportFcgm_Click" Cursor="Hand"/>
|
||||||
<Button Content="导入映射图" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,54,0,0" Click="ImportImg_Click"/>
|
<Button Content="导入映射图" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,54,0,0" Click="ImportImg_Click" Cursor="Hand"/>
|
||||||
<Button Content="保存航点" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,108,0,0" Click="ExportFcgm_Click"/>
|
<Button Content="保存航点" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,108,0,0" Click="ExportFcgm_Click" Cursor="Hand"/>
|
||||||
<Button Content="渲染" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,162,0,0" Click="Render_Click"/>
|
<Button Content="渲染" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,162,0,0" Click="Render_Click" Cursor="Hand"/>
|
||||||
<Button Content="3D绕行" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,270,0,0" Click="ByPass_Click"/>
|
<Button Content="智能对应错层" HorizontalAlignment="Left" VerticalAlignment="Top" Width="145" Height="49" Margin="0,216,0,0" Click="CollisionLayer_Click" Cursor="Hand"/>
|
||||||
<Button Content="绕行取消" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,324,0,0" Click="ByPassCancel_Click"/>
|
<Button Content="ID对应错层" HorizontalAlignment="Right" VerticalAlignment="Top" Width="70" Height="49" Margin="0,216,0,0" Click="CollisionLayer_Click" Cursor="Hand"/>
|
||||||
<TextBox Name="vLogBox" HorizontalAlignment="Center" VerticalAlignment="Top" Width="220" Height="284" Margin="0,378,0,0"/>
|
<Button Content="智能对应绕行" HorizontalAlignment="Left" VerticalAlignment="Top" Width="145" Height="49" Margin="0,270,0,0" Click="ByPass_Click" Cursor="Hand"/>
|
||||||
|
<Button Content="ID对应绕行" HorizontalAlignment="Right" VerticalAlignment="Top" Width="70" Height="49" Margin="0,270,0,0" Click="ByPass_Click" Cursor="Hand"/>
|
||||||
|
<Button Content="绕行取消" HorizontalAlignment="Left" VerticalAlignment="Top" Width="220" Height="49" Margin="0,324,0,0" Click="ByPassCancel_Click" Cursor="Hand"/>
|
||||||
|
<TextBox Name="vLogBox" HorizontalAlignment="Center" VerticalAlignment="Top" Width="220" Height="424" Margin="0,378,0,0" Cursor="AppStarting"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</Window>
|
</Window>
|
@ -40,19 +40,103 @@ namespace FlyCube
|
|||||||
//创建一个 主画布对象
|
//创建一个 主画布对象
|
||||||
TopCanvas = new MainCanvas(this.LayerPlane);
|
TopCanvas = new MainCanvas(this.LayerPlane);
|
||||||
|
|
||||||
Vector3 aVec = new Vector3(-6650, 1585.775, 3150);
|
//List<Vector3[]> abVecs = FileBase.TxtToPos("C:/Users/szdot/Desktop/1.txt", out string[] fightNames);//从txt文件里面读取航点 信息
|
||||||
Vector3 bVec = new Vector3(-3864.256, 126.145,0);
|
//Vector3[] aVecs = abVecs[0].ToArray();
|
||||||
List<Vector3> vecs = FlyVecFun.GetRingVec(aVec,bVec,0.3,100,1,1200);
|
//Vector3[] bVecs = abVecs[1].ToArray();
|
||||||
string txta = "";
|
//Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
||||||
for (int i = 0; i < vecs.Count; i++)
|
//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)
|
||||||
{
|
{
|
||||||
txta += i + " 0" + " " + vecs[i].X + " " + vecs[i].Y + " " + vecs[i].Z + "\r\n";
|
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);
|
||||||
}
|
}
|
||||||
if (File.Exists("C:/Users/szdot/Desktop/a.txt"))
|
else
|
||||||
{
|
{
|
||||||
File.Delete("C:/Users/szdot/Desktop/a.txt");
|
return;
|
||||||
}
|
}
|
||||||
SaveFile("C:/Users/szdot/Desktop/a.txt", txta);
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3D绕行
|
/// 3D绕行
|
||||||
@ -69,8 +153,7 @@ namespace FlyCube
|
|||||||
Vector3[] aVecs = abVecs[0].ToArray();
|
Vector3[] aVecs = abVecs[0].ToArray();
|
||||||
Vector3[] bVecs = abVecs[1].ToArray();
|
Vector3[] bVecs = abVecs[1].ToArray();
|
||||||
Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
Vector3[] new_bVecs = FlyVecFun.ContactABOut(aVecs, bVecs, StrPrint);
|
||||||
//Vector3[] new_aVecs = FlyVecFun.NormalPull(aVecs, bVecs, StrPrintAsync);
|
//Vector3[] new_aVecs = FlyVecFun.NormalPull(aVecs, bVecs, StrPrintAsync);//拉散图案
|
||||||
|
|
||||||
bool isPass;
|
bool isPass;
|
||||||
Task<List<List<Vector3>>> reTask = Task.Run(() => FlyVecFun.ABypassB(aVecs, bVecs, StrPrintAsync, GetVal, cts.Token, out isPass));
|
Task<List<List<Vector3>>> reTask = Task.Run(() => FlyVecFun.ABypassB(aVecs, bVecs, StrPrintAsync, GetVal, cts.Token, out isPass));
|
||||||
List<List<Vector3>> re = await reTask;
|
List<List<Vector3>> re = await reTask;
|
||||||
@ -99,7 +182,7 @@ namespace FlyCube
|
|||||||
}
|
}
|
||||||
if (re.Count > 0)
|
if (re.Count > 0)
|
||||||
{
|
{
|
||||||
string path = "C:/Users/szdot/Desktop/a.txt";
|
string path = $"C:/Users/szdot/Desktop/a.txt";
|
||||||
if (File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
File.Delete(path);
|
File.Delete(path);
|
||||||
@ -141,11 +224,7 @@ namespace FlyCube
|
|||||||
private void ByPassCancel_Click(object sender, RoutedEventArgs e)
|
private void ByPassCancel_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
cts.Cancel(); //取消掉 异步执行的 绕行函数
|
cts.Cancel(); //取消掉 异步执行的 绕行函数
|
||||||
}
|
cts = new CancellationTokenSource();
|
||||||
//异步回调函数 控制 取消绕行函数执行
|
|
||||||
private bool IsBreak(bool val)
|
|
||||||
{
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
// 异步回调函数 输出日志
|
// 异步回调函数 输出日志
|
||||||
private async void StrPrintAsync(string str)
|
private async void StrPrintAsync(string str)
|
||||||
@ -331,7 +410,7 @@ namespace FlyCube
|
|||||||
MessageBox.Show("成功");
|
MessageBox.Show("成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 灯光 组
|
/// 灯光 组
|
||||||
|
2
FlyCube/Properties/Settings.Designer.cs
generated
2
FlyCube/Properties/Settings.Designer.cs
generated
@ -12,7 +12,7 @@ namespace FlyCube.Properties {
|
|||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
Loading…
Reference in New Issue
Block a user