ParallellineSearch.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. namespace SimulationCommon;
  2. public struct Point
  3. {
  4. public double lat;
  5. public double lon;
  6. public Point(double lat, double lon)
  7. {
  8. this.lat = lat;
  9. this.lon = lon;
  10. }
  11. }
  12. public class ParallellineSearch
  13. {
  14. public static double calculateVectorAngle(double[] vector)
  15. {
  16. double vectorCos = vector[0] / Math.Sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
  17. double vectorAngle = 0;
  18. if (vector[1] >= 0)
  19. {
  20. vectorAngle = Math.Acos(vectorCos);
  21. }
  22. else if (vector[1] < 0)
  23. {
  24. vectorAngle = 2 * Math.PI - Math.Acos(vectorCos);
  25. }
  26. return vectorAngle;
  27. }
  28. public static Point movePointByVandA(double angle, double distance, Point startPoint, double[] vector)
  29. {
  30. ///定义并输出新坐标点
  31. Point finalPoint = new Point();
  32. //计算已知向量与x轴正方向的夹角
  33. double vectorAngle = calculateVectorAngle(vector);
  34. //计算目标点向量与x轴正方向的夹角
  35. vectorAngle += angle;
  36. //计算目标点向量夹角的正弦、余弦值
  37. double vectorAngleSin = Math.Sin(vectorAngle);
  38. double vectorAngleCos = Math.Cos(vectorAngle);
  39. //ArrayList<Double> XY = new ArrayList<Double>();
  40. finalPoint.lon = startPoint.lon + distance * vectorAngleCos;
  41. finalPoint.lat = startPoint.lat + distance * vectorAngleSin;
  42. return finalPoint;
  43. }
  44. /// <summary>
  45. ///
  46. /// </summary>
  47. /// <param name="plane"></param>
  48. /// <param name="RegionPoints"></param>
  49. /// <param name="sweepWidth">扫视宽度(需要换算成经纬度)sweepWidth = saruSweepWidth/(1.852 * 60) ;</param>
  50. /// <returns></returns>
  51. public static List<Point> parallellineSearch(Point plane, List<Point> RegionPoints, double sweepWidth)
  52. {
  53. Point[] points = new Point[4];
  54. points[0].lat = RegionPoints[0].lat;
  55. points[0].lon = RegionPoints[0].lon;
  56. points[1].lat = RegionPoints[1].lat;
  57. points[1].lon = RegionPoints[1].lon;
  58. points[2].lat = RegionPoints[2].lat;
  59. points[2].lon = RegionPoints[2].lon;
  60. points[3].lat = RegionPoints[3].lat;
  61. points[3].lon = RegionPoints[3].lon;
  62. List<Point> outputWaypoints = new List<Point>();
  63. int npIndex = 0; //最近点的索引nearestPoint
  64. double npDistance = Double.PositiveInfinity; //初始化最近距离为正无穷
  65. double midDistance = 0;
  66. for (int i = 0; i < points.Length; i++)
  67. {
  68. midDistance = Math.Sqrt(Math.Pow(points[i].lat - plane.lat, 2) + Math.Pow(points[i].lon - plane.lon, 2));
  69. if (midDistance < npDistance)
  70. {
  71. npDistance = midDistance;
  72. npIndex = i;
  73. }
  74. }
  75. //***找到最近点的领边哪个为长边,并定义长边方向与短边方向
  76. int lspIndex = 0; //longSidePointIndex
  77. int sspIndex = 0; //shortSidePointIndex
  78. //初始化长边索引与短边索引
  79. if (npIndex + 1 < 4)
  80. lspIndex = npIndex + 1;
  81. else
  82. lspIndex = npIndex + 1 - 4;
  83. if (npIndex - 1 < 0)
  84. sspIndex = npIndex - 1 + 4;
  85. else
  86. sspIndex = npIndex - 1;
  87. //计算长边的距离longSideDistance
  88. double lspDistance = Math.Sqrt(Math.Pow(points[npIndex].lat - points[lspIndex].lat, 2)
  89. + Math.Pow(points[npIndex].lon - points[lspIndex].lon, 2));
  90. //计算短边的距离shortSideDistance
  91. double sspDistance = Math.Sqrt(Math.Pow(points[npIndex].lat - points[sspIndex].lat, 2)
  92. + Math.Pow(points[npIndex].lon - points[sspIndex].lon, 2));
  93. //最终确定长边和短边的索引和长度
  94. int midIndex = 0;
  95. if (lspDistance < sspDistance)
  96. {
  97. //互换长边索引与短边索引的值
  98. midIndex = lspIndex;
  99. lspIndex = sspIndex;
  100. sspIndex = midIndex;
  101. //互换长边距离与短边距离
  102. midDistance = lspDistance;
  103. lspDistance = sspDistance;
  104. sspDistance = midDistance;
  105. }
  106. double[] lspDirection =
  107. { points[lspIndex].lon - points[npIndex].lon, points[lspIndex].lat - points[npIndex].lat };
  108. double[] sspDirection =
  109. { points[sspIndex].lon - points[npIndex].lon, points[sspIndex].lat - points[npIndex].lat };
  110. Point midWaypoint = new Point();
  111. //寻找路径规划的起点
  112. midWaypoint.lat = points[npIndex].lat;
  113. midWaypoint.lon = points[npIndex].lon;
  114. double pointnum = 0;
  115. //找到搜寻区域内路径的起点
  116. Point startWaypoint = new Point();
  117. startWaypoint.lat = movePointByVandA(0, sweepWidth / 2, midWaypoint, lspDirection).lat;
  118. startWaypoint.lon = movePointByVandA(0, sweepWidth / 2, midWaypoint, lspDirection).lon;
  119. midWaypoint.lat = startWaypoint.lat;
  120. midWaypoint.lon = startWaypoint.lon;
  121. startWaypoint.lat = movePointByVandA(0, sweepWidth / 2, midWaypoint, sspDirection).lat;
  122. startWaypoint.lon = movePointByVandA(0, sweepWidth / 2, midWaypoint, sspDirection).lon;
  123. //Console.WriteLine(startWaypoint.lon);
  124. //Console.WriteLine(startWaypoint.lat);
  125. //Console.WriteLine(sspDistance);
  126. //Console.WriteLine(lspDistance);
  127. outputWaypoints.Add(startWaypoint);
  128. pointnum++;
  129. midWaypoint.lat = startWaypoint.lat;
  130. midWaypoint.lon = startWaypoint.lon;
  131. //迭代计算搜寻区域内路径点
  132. double forwardDistance = sweepWidth / 2;
  133. double moveDistance;
  134. while (forwardDistance <= sspDistance)
  135. {
  136. //沿长边正方向移动longSideDistance-sweepWidth后的点
  137. moveDistance = lspDistance - sweepWidth;
  138. Point loopWaypoint1 = movePointByVandA(0, moveDistance, midWaypoint, lspDirection);
  139. outputWaypoints.Add(loopWaypoint1);
  140. pointnum++;
  141. midWaypoint.lat = loopWaypoint1.lat;
  142. midWaypoint.lon = loopWaypoint1.lon;
  143. //沿短边移动sweepWidth后的点
  144. moveDistance = sweepWidth;
  145. Point loopWaypoint2 = movePointByVandA(0, moveDistance, midWaypoint, sspDirection);
  146. outputWaypoints.Add(loopWaypoint2);
  147. pointnum++;
  148. midWaypoint.lat = loopWaypoint2.lat;
  149. midWaypoint.lon = loopWaypoint2.lon;
  150. forwardDistance += sweepWidth;
  151. if (forwardDistance > sspDistance)
  152. {
  153. break;
  154. }
  155. //沿长边负方向移动longSideDistance-sweepWidth后的点
  156. moveDistance = lspDistance - sweepWidth;
  157. Point loopWaypoint3 = movePointByVandA(Math.PI, moveDistance, midWaypoint, lspDirection);
  158. outputWaypoints.Add(loopWaypoint3);
  159. pointnum++;
  160. midWaypoint.lat = loopWaypoint3.lat;
  161. midWaypoint.lon = loopWaypoint3.lon;
  162. //沿短边移动sweepWidth后的点
  163. moveDistance = sweepWidth;
  164. Point loopWaypoint4 = movePointByVandA(0, moveDistance, midWaypoint, sspDirection);
  165. outputWaypoints.Add(loopWaypoint4);
  166. pointnum++;
  167. midWaypoint.lat = loopWaypoint4.lat;
  168. midWaypoint.lon = loopWaypoint4.lon;
  169. forwardDistance += sweepWidth;
  170. if (forwardDistance > sspDistance)
  171. {
  172. break;
  173. }
  174. }
  175. return outputWaypoints;
  176. }
  177. }