电子围栏推送服务
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

95 行
3.5KB

  1. namespace TelpoPush.Fence.Worker.Models.Fence
  2. {
  3. public static class CirclePolygonAlgorithm
  4. {
  5. /// <summary>
  6. /// 判断圆和多边形是否相交
  7. /// </summary>
  8. /// <param name="circle">圆心坐标</param>
  9. /// <param name="radius">圆半径</param>
  10. /// <param name="polygon">多边形各个点坐标</param>
  11. /// <returns></returns>
  12. public static bool IsIntersect(GpsFencePoint circle, double degree, IList<GpsFencePoint> polygon)
  13. {
  14. double powRadius = Math.Pow(degree, 2);
  15. //情况1:多边形任一顶点在圆内,则认为相交
  16. foreach (var pt in polygon)
  17. {
  18. if (Math.Pow(circle.Longitude - pt.Longitude, 2) + Math.Pow(circle.Latitude - pt.Latitude, 2) < powRadius) return true;
  19. }
  20. //情况2:多边形顶点集的任一有效线段和圆相交(圆心到线段的距离小于半径)
  21. var lines = EnumeratePolygonLines(polygon);
  22. foreach (var seg in lines)
  23. {
  24. if (PointToLine(circle, seg.Item1, seg.Item2) < degree) return true;
  25. }
  26. return false;
  27. }
  28. private static IList<Tuple<GpsFencePoint, GpsFencePoint>> EnumeratePolygonLines(IList<GpsFencePoint> polygon)
  29. {
  30. var list = new List<Tuple<GpsFencePoint, GpsFencePoint>>();
  31. for (int i = 0; i < polygon.Count - 1; i++)
  32. {
  33. list.Add(new Tuple<GpsFencePoint, GpsFencePoint>(polygon[i], polygon[i + 1]));
  34. }
  35. list.Add(new Tuple<GpsFencePoint, GpsFencePoint>(polygon[polygon.Count - 1], polygon[0]));
  36. return list;
  37. }
  38. //计算两点之间的距离
  39. private static double LineSpace(GpsFencePoint ptStart, GpsFencePoint ptEnd)
  40. {
  41. if (ptStart == ptEnd) return 0;
  42. return Math.Sqrt((ptEnd.Longitude - ptStart.Longitude) * (ptEnd.Longitude - ptStart.Longitude) + (ptEnd.Latitude - ptStart.Latitude) * (ptEnd.Latitude - ptStart.Latitude));
  43. }
  44. /// <summary>
  45. /// 点到线段的距离
  46. /// </summary>
  47. /// <param name="pt"></param>
  48. /// <param name="ptStart">线段顶点1</param>
  49. /// <param name="ptEnd">线段顶点2</param>
  50. /// <returns></returns>
  51. private static double PointToLine(GpsFencePoint pt, GpsFencePoint ptStart, GpsFencePoint ptEnd)
  52. {
  53. double distance = 0;
  54. double a, b, c;
  55. a = LineSpace(ptStart, ptEnd); //线段长度
  56. b = LineSpace(pt, ptStart); //点到线段顶点1的距离
  57. c = LineSpace(pt, ptEnd); //点到线段顶点2的距离
  58. if (b == 0 || c == 0)
  59. {
  60. distance = 0;
  61. return distance;
  62. }
  63. if (a == 0)
  64. {
  65. distance = b;
  66. return distance;
  67. }
  68. if (c * c >= a * a + b * b)
  69. {
  70. distance = b;
  71. return distance;
  72. }
  73. if (b * b >= a * a + c * c)
  74. {
  75. distance = c;
  76. return distance;
  77. }
  78. double p = (a + b + c) / 2; //半周长
  79. double s = Math.Sqrt(p * (p - a) * (p - b) * (p - c)); // 海伦公式求面积
  80. distance = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
  81. return distance;
  82. }
  83. }
  84. }