namespace SimulationCommon; public struct Point { public double lat; public double lon; public Point(double lat, double lon) { this.lat = lat; this.lon = lon; } } public class ParallellineSearch { public static double calculateVectorAngle(double[] vector) { double vectorCos = vector[0] / Math.Sqrt(vector[0] * vector[0] + vector[1] * vector[1]); double vectorAngle = 0; if (vector[1] >= 0) { vectorAngle = Math.Acos(vectorCos); } else if (vector[1] < 0) { vectorAngle = 2 * Math.PI - Math.Acos(vectorCos); } return vectorAngle; } public static Point movePointByVandA(double angle, double distance, Point startPoint, double[] vector) { ///定义并输出新坐标点 Point finalPoint = new Point(); //计算已知向量与x轴正方向的夹角 double vectorAngle = calculateVectorAngle(vector); //计算目标点向量与x轴正方向的夹角 vectorAngle += angle; //计算目标点向量夹角的正弦、余弦值 double vectorAngleSin = Math.Sin(vectorAngle); double vectorAngleCos = Math.Cos(vectorAngle); //ArrayList XY = new ArrayList(); finalPoint.lon = startPoint.lon + distance * vectorAngleCos; finalPoint.lat = startPoint.lat + distance * vectorAngleSin; return finalPoint; } /// /// /// /// /// /// 扫视宽度(需要换算成经纬度)sweepWidth = saruSweepWidth/(1.852 * 60) ; /// public static List parallellineSearch(Point plane, List RegionPoints, double sweepWidth) { Point[] points = new Point[4]; points[0].lat = RegionPoints[0].lat; points[0].lon = RegionPoints[0].lon; points[1].lat = RegionPoints[1].lat; points[1].lon = RegionPoints[1].lon; points[2].lat = RegionPoints[2].lat; points[2].lon = RegionPoints[2].lon; points[3].lat = RegionPoints[3].lat; points[3].lon = RegionPoints[3].lon; List outputWaypoints = new List(); int npIndex = 0; //最近点的索引nearestPoint double npDistance = Double.PositiveInfinity; //初始化最近距离为正无穷 double midDistance = 0; for (int i = 0; i < points.Length; i++) { midDistance = Math.Sqrt(Math.Pow(points[i].lat - plane.lat, 2) + Math.Pow(points[i].lon - plane.lon, 2)); if (midDistance < npDistance) { npDistance = midDistance; npIndex = i; } } //***找到最近点的领边哪个为长边,并定义长边方向与短边方向 int lspIndex = 0; //longSidePointIndex int sspIndex = 0; //shortSidePointIndex //初始化长边索引与短边索引 if (npIndex + 1 < 4) lspIndex = npIndex + 1; else lspIndex = npIndex + 1 - 4; if (npIndex - 1 < 0) sspIndex = npIndex - 1 + 4; else sspIndex = npIndex - 1; //计算长边的距离longSideDistance double lspDistance = Math.Sqrt(Math.Pow(points[npIndex].lat - points[lspIndex].lat, 2) + Math.Pow(points[npIndex].lon - points[lspIndex].lon, 2)); //计算短边的距离shortSideDistance double sspDistance = Math.Sqrt(Math.Pow(points[npIndex].lat - points[sspIndex].lat, 2) + Math.Pow(points[npIndex].lon - points[sspIndex].lon, 2)); //最终确定长边和短边的索引和长度 int midIndex = 0; if (lspDistance < sspDistance) { //互换长边索引与短边索引的值 midIndex = lspIndex; lspIndex = sspIndex; sspIndex = midIndex; //互换长边距离与短边距离 midDistance = lspDistance; lspDistance = sspDistance; sspDistance = midDistance; } double[] lspDirection = { points[lspIndex].lon - points[npIndex].lon, points[lspIndex].lat - points[npIndex].lat }; double[] sspDirection = { points[sspIndex].lon - points[npIndex].lon, points[sspIndex].lat - points[npIndex].lat }; Point midWaypoint = new Point(); //寻找路径规划的起点 midWaypoint.lat = points[npIndex].lat; midWaypoint.lon = points[npIndex].lon; double pointnum = 0; //找到搜寻区域内路径的起点 Point startWaypoint = new Point(); startWaypoint.lat = movePointByVandA(0, sweepWidth / 2, midWaypoint, lspDirection).lat; startWaypoint.lon = movePointByVandA(0, sweepWidth / 2, midWaypoint, lspDirection).lon; midWaypoint.lat = startWaypoint.lat; midWaypoint.lon = startWaypoint.lon; startWaypoint.lat = movePointByVandA(0, sweepWidth / 2, midWaypoint, sspDirection).lat; startWaypoint.lon = movePointByVandA(0, sweepWidth / 2, midWaypoint, sspDirection).lon; //Console.WriteLine(startWaypoint.lon); //Console.WriteLine(startWaypoint.lat); //Console.WriteLine(sspDistance); //Console.WriteLine(lspDistance); outputWaypoints.Add(startWaypoint); pointnum++; midWaypoint.lat = startWaypoint.lat; midWaypoint.lon = startWaypoint.lon; //迭代计算搜寻区域内路径点 double forwardDistance = sweepWidth / 2; double moveDistance; while (forwardDistance <= sspDistance) { //沿长边正方向移动longSideDistance-sweepWidth后的点 moveDistance = lspDistance - sweepWidth; Point loopWaypoint1 = movePointByVandA(0, moveDistance, midWaypoint, lspDirection); outputWaypoints.Add(loopWaypoint1); pointnum++; midWaypoint.lat = loopWaypoint1.lat; midWaypoint.lon = loopWaypoint1.lon; //沿短边移动sweepWidth后的点 moveDistance = sweepWidth; Point loopWaypoint2 = movePointByVandA(0, moveDistance, midWaypoint, sspDirection); outputWaypoints.Add(loopWaypoint2); pointnum++; midWaypoint.lat = loopWaypoint2.lat; midWaypoint.lon = loopWaypoint2.lon; forwardDistance += sweepWidth; if (forwardDistance > sspDistance) { break; } //沿长边负方向移动longSideDistance-sweepWidth后的点 moveDistance = lspDistance - sweepWidth; Point loopWaypoint3 = movePointByVandA(Math.PI, moveDistance, midWaypoint, lspDirection); outputWaypoints.Add(loopWaypoint3); pointnum++; midWaypoint.lat = loopWaypoint3.lat; midWaypoint.lon = loopWaypoint3.lon; //沿短边移动sweepWidth后的点 moveDistance = sweepWidth; Point loopWaypoint4 = movePointByVandA(0, moveDistance, midWaypoint, sspDirection); outputWaypoints.Add(loopWaypoint4); pointnum++; midWaypoint.lat = loopWaypoint4.lat; midWaypoint.lon = loopWaypoint4.lon; forwardDistance += sweepWidth; if (forwardDistance > sspDistance) { break; } } return outputWaypoints; } }