Compare commits

..

10 Commits

Author SHA1 Message Date
tk
49484ca152 【类 型】:refactor
【主	题】:界面修改
【描	述】:
	[原因]:
	[过程]:
	[影响]:
【结	束】

# 类型 包含:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
2024-06-24 16:24:25 +08:00
szdot
ee1f47a448 碰撞检测 距离参数改为5米 2024-04-03 10:28:28 +08:00
szdot
cf4a484d64 npne 2024-01-24 16:12:57 +08:00
szdot
bb6ca71c78 none 2024-01-24 16:10:20 +08:00
szdot
4cd26f6b62 NormalPull 拉散函数 加入判断第一个图案是否是平面 2024-01-24 16:05:10 +08:00
szdot
3a6de2e67f 智能路径ContactABOut 增加静态跳过功能 2024-01-23 18:18:35 +08:00
szdot
aa30959d71 增加 点to面投影函数 检测最多点共面函数 修改错层函数(现在不判断是否是平面 是否共面 支持多层直接错层 不成功返回 re长度为0) 2024-01-19 14:38:31 +08:00
szdot
b53fa88b7d 拉散修改 2024-01-17 20:25:54 +08:00
szdot
48bdb1e650 GetRingVec函数 设置了圆盘最小值为3米范围
NormalPull函数 增加了判断是否是矩阵的 判断返回 null则判定为不是矩阵
2024-01-17 18:11:43 +08:00
szdot
2944715bab 注释修改 2024-01-17 16:43:36 +08:00
13 changed files with 424 additions and 238 deletions

View File

@ -411,7 +411,7 @@ namespace FlightRouteV2
/// <summary>
/// 飞行过程中间距 平方值
/// </summary>
public static double SpaceBetweenSquare { get; set; } = 62500;
public static double SpaceBetweenSquare { get; set; } = 250000;
/// <summary>
/// 算绕行时 中间取点 true在正中间取点即 一个圆盘 false在一个圆柱体内取点
/// </summary>
@ -648,40 +648,34 @@ namespace FlightRouteV2
return new_bVecs;
}
/// <summary>
/// 从一组向量集合中 不重复的随机选择4个向量为一组 最多100组 组合成二维数组 如:[[1,2,3,4][5,6,7,8]...]
/// 从数组中删除指定索引处的元素
/// </summary>
/// <param name="vecs">坐标集和</param>
/// <returns>re空数组则代表不够4个坐标 </returns>
private static List<Vector3[]> RandomSel4Vec(Vector3[] vecs)
/// <typeparam name="T">数组元素类型</typeparam>
/// <param name="array">要操作的数组</param>
/// <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;
// 如果坐标数组少于4个或者为空则返回空列表
if (len < 4)
// 检查索引是否有效
if (indicesToRemove == null || indicesToRemove.Count == 0)
{
return result;
// 没有要删除的索引,返回原数组
return array;
}
// 确定最大可选择的组数最多为100组
int numGroups = Math.Min(len / 4, 100);
List<Vector3> flattenedList = vecs.ToList();
Random random = new Random();
// 遍历每一组
for (int i = 0; i < numGroups; i++)
// 创建一个新数组,长度为原数组长度减去要删除的元素数量
T[] newArray = new T[array.Length - indicesToRemove.Count];
int newIndex = 0;
// 复制不包括指定索引的元素到新数组中
for (int i = 0; i < array.Length; i++)
{
List<Vector3> selectedGroup = new List<Vector3>();
// 随机选择4个不重复的坐标
for (int j = 0; j < 4; j++)
if (!indicesToRemove.Contains(i))
{
int index = random.Next(flattenedList.Count);
selectedGroup.Add(flattenedList[index]);
flattenedList.RemoveAt(index);
newArray[newIndex] = array[i];
newIndex++;
}
// 将选择的坐标组成的 List 转换为数组,并添加到结果中
result.Add(selectedGroup.ToArray());
}
return result;
// 返回新数组
return newArray;
}
/// <summary>
/// 设置中间航点
@ -725,7 +719,7 @@ namespace FlightRouteV2
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
}
/// <summary>
/// 叉积
/// 叉积 ps法线向量
/// </summary>
/// <param name="v1">向量1</param>
/// <param name="v2">向量2</param>
@ -743,7 +737,7 @@ namespace FlightRouteV2
/// <param name="v1">第一个向量</param>
/// <param name="v2">第二个向量</param>
/// <returns>角度</returns>
public static double AngleBetween(Vector3 v1, Vector3 v2)
private static double AngleBetween(Vector3 v1, Vector3 v2)
{
// 计算点积
double dotProduct = DotPro(v1, v2);
@ -761,6 +755,77 @@ namespace FlightRouteV2
return thetaDegrees;
}
/// <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个点是否在一个平面上
/// </summary>
/// <param name="vector1">点1</param>
@ -768,14 +833,14 @@ namespace FlightRouteV2
/// <param name="vector3">点3</param>
/// <param name="vector4">点4</param>
/// <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 v1v3 = vec3 - 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();
//设置一个阈值,判断是否共面
@ -806,7 +871,7 @@ namespace FlightRouteV2
else return false;
}
/// <summary>
/// 从顶视图 判断点是否在两条内之间
/// 从顶视图 判断点是否在两条线内之间
/// </summary>
/// <param name="A">线段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)
{
/// 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);
C = new Vector3(C.X, 0, C.Z);
D = new Vector3(D.X, 0, D.Z);
@ -1140,7 +1205,7 @@ namespace FlightRouteV2
/// <param name="aVecs">始点坐标集合</param>
/// <param name="bVecs">终点坐标集合</param>
/// <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[]>(); //所有碰撞的组
int planeCou = aVecs.Length; //获取飞机总数
@ -1169,7 +1234,7 @@ namespace FlightRouteV2
/// <param name="aVecs">始点坐标集合</param>
/// <param name="bVecs">终点坐标集合</param>
/// <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[]>(); //所有碰撞的组
int planeCou = aVecs.Count; //获取飞机总数
@ -1302,15 +1367,43 @@ namespace FlightRouteV2
/// <param name="aVecs">起始点坐标组</param>
/// <param name="bVecs">目标点坐标组</param>
/// <param name="StrPrint">日志输出 回调函数</param>
/// <param name="isStaticSkip">静态跳过 true跳过即保持原地不动 false不跳过参与“最近和交换”计算</param>
/// <param name="staticThresholdSquare">静态距离判断 小于阈值判定为静态 注意是个平方值</param>
/// <param name="isSwap">交叉航线是否进行交换</param>
/// <param name="swapCount">交换次数</param>
/// <param name="crossingLimit">交叉线路数量上限 ps:超过这个数量则不进行交换</param>
/// <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();
StrPrint("-------智能选择路径计算,开始-------");
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对应关系
///记录a b集合索引
List<int> aIndex = new List<int>();
@ -1330,8 +1423,8 @@ namespace FlightRouteV2
List<Vector3> allVecs = new List<Vector3>();
for (int i = 0; i < remainCou; i++)
{
allVecs.Add(aVecs[aIndex[i]]);
allVecs.Add(bVecs[bIndex[i]]);
allVecs.Add(new_aVecs[aIndex[i]]);
allVecs.Add(new_bVecs[bIndex[i]]);
}
Vector3 centerVec = GetPosCenter(allVecs);//重心点
// 遍历所有ab点距离重心点的距离
@ -1339,8 +1432,8 @@ namespace FlightRouteV2
double[] bLens = new double[remainCou];
for (int i = 0; i < remainCou; i++)
{
aLens[i] = GageLengthSquare(aVecs[aIndex[i]], centerVec);
bLens[i] = GageLengthSquare(bVecs[bIndex[i]], centerVec);
aLens[i] = GageLengthSquare(new_aVecs[aIndex[i]], centerVec);
bLens[i] = GageLengthSquare(new_bVecs[bIndex[i]], centerVec);
}
// 找出ab集合最外层坐标的下标 即离重心点最远的点
int aMaxIndex = GetIndexOfMaxOrMin(aLens); // a集合到重心点最长的距离 数组的下标
@ -1350,7 +1443,7 @@ namespace FlightRouteV2
double[] outAtoBLen = new double[remainCou];//最外层A点到 B集合所有点的距离
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);// 最短距离
match.Add(new int[] { aIndex[aMaxIndex], bIndex[bMinIndex] });// 映射到配对
@ -1362,7 +1455,7 @@ namespace FlightRouteV2
double[] outBtoALen = new double[remainCou];//最外层B点到 A集合所有点的距离
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);// 最短距离
match.Add(new int[] { aIndex[aMinIndex], bIndex[bMaxIndex] });// 映射到配对
@ -1370,89 +1463,105 @@ namespace FlightRouteV2
bIndex.RemoveAt(bMaxIndex); // 删除已经配对的b集合 ID
}
}
Vector3[] new_bVecs = CreateNewBVecs(bVecs, match);// 按照映射 获取a 对应的 新的b集合
if (!isSwap)
{
return new_bVecs;
}
Vector3[] re_bVecs = CreateNewBVecs(new_bVecs, match);// 按照映射 获取a 对应的 新的b集合
///交叉 交换
for (int i = 0; i < swapCount; i++)
if (isSwap)
{
List<int[]> planesCollision = AirImitation(aVecs, new_bVecs);// 获取碰撞组
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)
for (int i = 0; i < swapCount; i++)
{
log += "[";
foreach (int itemInt in item)
List<int[]> planesCollision = AirImitation(new_aVecs, re_bVecs);// 获取碰撞组
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}。");
/// 遍历所有交叉组 分组做交换
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)
StrPrint($"共迭代{swapCount}次交换,第{i}次。共{filteredCollision.Count}组,交换组为:{log}。");
/// 遍历所有交叉组 分组做交换
int cou = 0;
foreach (List<int> swap_indices in filteredCollision)
{
Vector3[] current_array = new Vector3[planeCou];
Array.Copy(new_bVecs, current_array, planeCou);//复制一个new_bVecs 副本
for (int k = 0; k < indices.Count; k++)
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)
{
current_array[original[k]] = new_bVecs[indices[k]];
}
///把最少碰撞的排列 录入到数组
int collisionsCou = (AirImitation(aVecs, current_array)).Count;//此排列的碰撞次数
if (tempLen.Count == 0 || tempLen[0] == collisionsCou)//如果第一次添加 或者 碰撞次数等于最少碰撞
{
///录入数组
tempLen.Add(collisionsCou);
tempNew_bVecsS.Add(current_array);
}
else if (tempLen[0] > collisionsCou)
{
/// 如果最小值 大于 当前碰撞次数,清空之前记录
tempLen.Clear();
tempNew_bVecsS.Clear();
///录入数组
tempLen.Add(collisionsCou);
tempNew_bVecsS.Add(current_array);
Vector3[] current_array = new Vector3[planeCou];
Array.Copy(re_bVecs, current_array, planeCou);//复制一个re_bVecs 副本
for (int k = 0; k < indices.Count; k++)
{
current_array[original[k]] = re_bVecs[indices[k]];
}
///把最少碰撞的排列 录入到数组
int collisionsCou = (AirImitation(new_aVecs, current_array)).Count;//此排列的碰撞次数
if (tempLen.Count == 0 || tempLen[0] == collisionsCou)//如果第一次添加 或者 碰撞次数等于最少碰撞
{
///录入数组
tempLen.Add(collisionsCou);
tempNew_bVecsS.Add(current_array);
}
else if (tempLen[0] > collisionsCou)
{
/// 如果最小值 大于 当前碰撞次数,清空之前记录
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;
StrPrint($"用时:{t}秒");
StrPrint($"-------智能选择路径计算,结束-------");
return new_bVecs;
return re_bVecs;
}
/// <summary>
/// 智能错层
/// </summary>
/// <param name="aVecs">起始坐标集合</param>
/// <param name="bVecs">终点做标集合</param>
/// <param name="aName">起始坐标航点名称</param>
/// <param name="bName">终点坐标航点名称</param>
/// <param name="StrPrint">日志输出 回调函数</param>
/// <param name="layHight">错层层高</param>
/// <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();
StrPrint("-------错层,开始-------");
@ -1467,102 +1576,73 @@ namespace FlightRouteV2
}
//获取飞机总数
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;
}
///共面上取三个点
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 side2 = vec2 - vec0;
Vector3 normal = CrossPro(side1, side2);
Vector3 normalScalar = normal.NormalizEd();//法线标量
//开始错层
///开始错层
for (int i = 0; i < planeCou; i++)
{
int shiftCou = 1; //记录循环次数 即层数
Vector3 aOrigin = aVecs[i]; //原点位置
Vector3 bOrigin = bVecs[i]; //原点位置
while (OnlyImitation(i, aVecs, bVecs))
Vector3 aOrigin = new_aVecs[i]; //原点位置
Vector3 bOrigin = new_bVecs[i]; //原点位置
while (OnlyImitation(i, new_aVecs, new_bVecs))
{
Vector3 shiftVec = normalScalar * ((shiftCou + 1) / 2 * layHight);
if (shiftCou % 2 == 1)
{
aVecs[i] = aOrigin + shiftVec;
bVecs[i] = bOrigin + shiftVec;
new_aVecs[i] = aOrigin + shiftVec;
new_bVecs[i] = bOrigin + shiftVec;
}
else
{
aVecs[i] = aOrigin - shiftVec;
bVecs[i] = bOrigin - shiftVec;
new_aVecs[i] = aOrigin - shiftVec;
new_bVecs[i] = bOrigin - shiftVec;
}
shiftCou += 1;
}
}
re.Add(aVecs.ToList());
re.Add(bVecs.ToList());
StrPrint($"错层成功");
///计算碰撞
planesCollision = AirImitation(aVecs, new_aVecs).Concat(AirImitation(new_aVecs, new_bVecs)).ToList(); //获取碰撞组
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;
StrPrint($"用时:{t}秒");
StrPrint($"-------错层结束-------");
@ -1574,10 +1654,12 @@ namespace FlightRouteV2
/// <param name="aVecs">起始坐标集合</param>
/// <param name="bVecs">终点做标集合</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="mappingId">飞机真实序号的映射关系</param>
/// <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;
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
@ -1618,14 +1700,14 @@ namespace FlightRouteV2
if (cancellationToken.IsCancellationRequested)//外部法取消指令
{
StrPrint("-------3D绕行操作被取消-------");
return re; // 退出函数
return null; // 退出函数
}
int progress = 0;//进度
foreach (int i in collisionGroup)//开始绕碰撞组
{
progress++;
GetVal(progress/collisionGroup.Count*100);
List<Vector3> grv = GetRingVec(aVecs[i], bVecs[i], 0.5, 5, 4, 1500);//中间可绕行航点列表
GetVal(progress / collisionGroup.Count * 100);
List<Vector3> grv = GetRingVec(aVecs[i], bVecs[i], 0.5, 5, 4, 1500, 300);//中间可绕行航点列表
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{grv.Count}次");
foreach (Vector3 v in grv)
{
@ -1680,7 +1762,7 @@ namespace FlightRouteV2
if (cancellationToken.IsCancellationRequested)//外部法取消指令
{
StrPrint("-------3D绕行操作被取消-------");
return re; // 退出函数
return null; // 退出函数
}
int progress = 0;//进度
foreach (int i in collisionGroup)//开始绕碰撞组
@ -1688,9 +1770,9 @@ namespace FlightRouteV2
progress++;
GetVal(progress / collisionGroup.Count * 100);
//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]);
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]);
StrPrint($"进度:{progress}/{collisionGroup.Count},本次绕行{sgrv1.Count * sgrv2.Count}次");
foreach (Vector3 v1 in sgrv1)
@ -1753,7 +1835,7 @@ namespace FlightRouteV2
if (cancellationToken.IsCancellationRequested)//外部法取消指令
{
StrPrint("-------3D绕行操作被取消-------");
return re; // 退出函数
return null; // 退出函数
}
int progress = 0;//进度
foreach (int i in collisionGroup)//开始绕碰撞组
@ -1761,11 +1843,11 @@ namespace FlightRouteV2
GetVal(progress / collisionGroup.Count * 100);
progress++;
//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]);
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]);
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}次");
foreach (Vector3 vm in grv)
{
@ -1776,7 +1858,7 @@ namespace FlightRouteV2
foreach (Vector3 v2 in sgrv2)
{
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;
break;
@ -1867,7 +1949,7 @@ namespace FlightRouteV2
/// <param name="layHight">偏移层高</param>
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
/// <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帽
Vector3 k_hat = (bVec - aVec).NormalizEd();
@ -1892,7 +1974,7 @@ namespace FlightRouteV2
{
offShift = middleProportion + offCount * layHight / length;
}
else if(direction == "backward")
else if (direction == "backward")
{
offShift = middleProportion - offCount * layHight / length;
}
@ -1929,17 +2011,20 @@ namespace FlightRouteV2
/// <param name="maxPaunchRadius">设定圆盘半径 的最大值 单位是厘米</param>
/// <param name="direction">层排布方向 "retrun"前后堆叠 "forward"向前排列(如:起点向目标点方向) "backward"向后排列</param>
/// <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>(); //记录所有绕行中间航点坐标
/// 根据a到b的长度 算出中间绕行几圈
double discRadius = GageLength(aVec, bVec) / paunch;//圆盘半径
if (discRadius > maxPaunchRadius)
{
discRadius = maxPaunchRadius;//设定圆盘不经不超过最大值
discRadius = maxPaunchRadius;//设定圆盘直径上限
}
int ringCou = (int)Math.Ceiling(discRadius / transfer ); //算层数和圈数 ps:层的厚度 和 圈的直径 为 paunch/航线长度
if (ringCou < 2) ringCou = 2; //最少两圈 两层
if (discRadius < minPaunchRadius)
{
discRadius = minPaunchRadius;//设定圆盘直径下限
}
int ringCou = (int)Math.Ceiling(discRadius / transfer); //算层数和圈数 ps:层的厚度 和 圈的直径 为 paunch/航线长度
/// 不是单圈的话 设置层数跟圈数相等
int layCou = ringCou;
if (singleCircle) layCou = 1;
@ -1971,30 +2056,48 @@ namespace FlightRouteV2
/// <param name="aVecs">平面图案坐标组</param>
/// <param name="bVecs">回归矩阵坐标组</param>
/// <param name="strPrint">日志输出 回调函数</param>
/// <param name="pullingDistance">拉散层距</param>
/// <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_bVecs = bVecs.ToArray();
Vector3[] new_aVecs = aVecs.ToArray(); //a图副本
Vector3[] new_bVecs = bVecs.ToArray(); //矩阵副本
int planeCou = new_aVecs.Length; //获取飞机总数
///判断a图是不是平面
if (!(planeCou == FindMaxPlaneIndices(aVecs).Count))
{
StrPrint("-------前图航点非平面图形,故不能做拉散图案操作-------");
return null;
}
///a图b图 中心
Vector3 aCenterPos = GetPosCenter(new_aVecs, false);
Vector3 bCenterPos = GetPosCenter(new_bVecs, false);
///判断bVec 矩阵的数量长宽
for (int i = 0; i < planeCou; i++)//把矩阵高度压平
{
new_bVecs[i] = new Vector3(new_bVecs[i].X, 0, new_bVecs[i].Z);
}
int row = 1 ;
for (int i = 0; i < planeCou-2; i++)
int row = 1;
for (int i = 0; i < planeCou - 2; i++)
{
if (!(IsVecsOnLine(new_bVecs[i], new_bVecs[i + 1], new_bVecs[i + 2])))
{
row = i+2;//列
row = i + 2;//列
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图的法线标量
Vector3 side1 = new_aVecs[1] - new_aVecs[0];
Vector3 side2 = new_aVecs[2] - new_aVecs[0];
@ -2014,20 +2117,20 @@ namespace FlightRouteV2
for (int i = 0; i < ran; i++)
{
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]))
{
new_aVecs[cou] -= normalScalar * (row - k) * 300;//左方
new_aVecs[cou] -= normalScalar * (row - k) * pullingDistance;//左方
}
else
{
new_aVecs[cou] += normalScalar * k * 300;//右方
new_aVecs[cou] += normalScalar * k * pullingDistance;//右方
}
}
}
///判断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]))//判断最大偏移量 是第一排 还是最后一排
{
@ -2056,15 +2159,16 @@ namespace FlightRouteV2
for (int i = 0; i < 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)]))
{
new_aVecs[cou] -= normalScalar * (ran - k) * 300;//上方
new_aVecs[cou] -= normalScalar * (ran - k) * pullingDistance;//上方
}
else
{
new_aVecs[cou] += normalScalar * k * 300;//下方
new_aVecs[cou] += normalScalar * k * pullingDistance;//下方
}
}
}

View File

@ -18,13 +18,16 @@
</Grid>
<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,54,0,0" Click="ImportImg_Click"/>
<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,162,0,0" Click="Render_Click"/>
<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="220" Height="49" Margin="0,324,0,0" Click="ByPassCancel_Click"/>
<TextBox Name="vLogBox" HorizontalAlignment="Center" VerticalAlignment="Top" Width="220" Height="284" Margin="0,378,0,0"/>
<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" Cursor="Hand"/>
<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" Cursor="Hand"/>
<Button Content="智能对应错层" HorizontalAlignment="Left" VerticalAlignment="Top" Width="145" Height="49" Margin="0,216,0,0" Click="CollisionLayer_Click" Cursor="Hand"/>
<Button Content="ID对应错层" HorizontalAlignment="Right" VerticalAlignment="Top" Width="70" Height="49" Margin="0,216,0,0" Click="CollisionLayer_Click" Cursor="Hand"/>
<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>
</WrapPanel>
</Window>

View File

@ -40,19 +40,103 @@ namespace FlyCube
//创建一个 主画布对象
TopCanvas = new MainCanvas(this.LayerPlane);
Vector3 aVec = new Vector3(-6650, 1585.775, 3150);
Vector3 bVec = new Vector3(-3864.256, 126.145,0);
List<Vector3> vecs = FlyVecFun.GetRingVec(aVec,bVec,0.3,100,1,1200);
string txta = "";
for (int i = 0; i < vecs.Count; i++)
//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)
{
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>
/// 3D绕行
@ -69,8 +153,7 @@ namespace FlyCube
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);
//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;
@ -99,7 +182,7 @@ namespace FlyCube
}
if (re.Count > 0)
{
string path = "C:/Users/szdot/Desktop/a.txt";
string path = $"C:/Users/szdot/Desktop/a.txt";
if (File.Exists(path))
{
File.Delete(path);
@ -141,11 +224,7 @@ namespace FlyCube
private void ByPassCancel_Click(object sender, RoutedEventArgs e)
{
cts.Cancel(); //取消掉 异步执行的 绕行函数
}
//异步回调函数 控制 取消绕行函数执行
private bool IsBreak(bool val)
{
return val;
cts = new CancellationTokenSource();
}
// 异步回调函数 输出日志
private async void StrPrintAsync(string str)

View File

@ -12,7 +12,7 @@ namespace FlyCube.Properties {
[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 {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));