电子围栏推送服务
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

145 rindas
4.8KB

  1. using System.Drawing;
  2. namespace TelpoPush.Fence.Worker.Models.Fence
  3. {
  4. public static class GeofenceHelper
  5. {
  6. public static double CalcDisgreeFromRadius(int radius)
  7. {
  8. double metersPerSecond = 30.0;
  9. double seconds = radius / metersPerSecond;
  10. return seconds / 3600;
  11. }
  12. /// <summary>
  13. /// 计算点是否在多边形内
  14. /// </summary>
  15. /// <param name="polygon">多边形点集合</param>
  16. /// <param name="pt">要判断的点</param>
  17. /// <returns>是否在多边形内</returns>
  18. public static bool IsPolygonContainsPoint(IList<GpsFencePoint> polygon, GpsFencePoint pt)
  19. {
  20. return RayCastingAlgorithm.IsWithin(pt, polygon, true);
  21. }
  22. /// <summary>
  23. /// 判断圆是否和多边形相交
  24. /// </summary>
  25. /// <param name="polygon">多边形点集合</param>
  26. /// <param name="ptCenter">要判断的圆的圆心点</param>
  27. /// <param name="radius">圆半径(单位米)</param>
  28. /// <returns></returns>
  29. public static bool IsPolygonIntersectCircle(IList<GpsFencePoint> polygon, GpsFencePoint ptCenter,int radius)
  30. {
  31. var degree = CalcDisgreeFromRadius(radius);
  32. return CirclePolygonAlgorithm.IsIntersect(ptCenter, degree, polygon);
  33. }
  34. //---yl---新增-- 2022.6.13----
  35. /// <summary>
  36. /// 判断圆和多边形是否相交
  37. /// </summary>
  38. /// <param name="circle">圆心坐标</param>
  39. /// <param name="radius">圆半径</param>
  40. /// <param name="polygon">多边形各个点坐标</param>
  41. /// <returns></returns>
  42. public static bool IsCircle2Polygon(Point circle, double radius, IList<Point> polygon)
  43. {
  44. bool res = false;
  45. double powRadius = Math.Pow(radius, 2);
  46. //情况1:多边形任一顶点在圆内,则认为相交
  47. foreach (var pt in polygon)
  48. {
  49. if (Math.Pow(circle.X - pt.X, 2) + Math.Pow(circle.Y - pt.Y, 2) < powRadius)
  50. {
  51. res = true;
  52. return res;
  53. //return true;
  54. }
  55. }
  56. //情况2:多边形顶点集的任一有效线段和圆相交(圆心到线段的距离小于半径)
  57. var lines = EnumeratePolygonLines(polygon);
  58. foreach (var seg in lines)
  59. {
  60. if (PointToLine(circle, seg.Item1, seg.Item2) < radius)
  61. {
  62. res = true;
  63. return res;
  64. //return true;
  65. }
  66. //return true;
  67. }
  68. return res;// false;
  69. }
  70. private static IList<Tuple<Point, Point>> EnumeratePolygonLines(IList<Point> polygon)
  71. {
  72. var list = new List<Tuple<Point, Point>>();
  73. for (int i = 0; i < polygon.Count - 1; i++)
  74. {
  75. list.Add(new Tuple<Point, Point>(polygon[i], polygon[i + 1]));
  76. }
  77. list.Add(new Tuple<Point, Point>(polygon[polygon.Count - 1], polygon[0]));
  78. return list;
  79. }
  80. //计算两点之间的距离
  81. private static double LineSpace(Point ptStarts, Point ptEnds)
  82. {
  83. if (ptStarts == ptEnds) return 0;
  84. return Math.Sqrt((ptEnds.X - ptStarts.X) * (ptEnds.X - ptStarts.X) + (ptEnds.Y - ptStarts.Y) * (ptEnds.Y - ptStarts.Y));
  85. }
  86. /// <summary>
  87. /// 点到线段的距离
  88. /// </summary>
  89. /// <param name="pt"></param>
  90. /// <param name="ptStart">线段顶点1</param>
  91. /// <param name="ptEnd">线段顶点2</param>
  92. /// <returns></returns>
  93. private static double PointToLine(Point pt, Point ptStart, Point ptEnd)
  94. {
  95. double distance = 0;
  96. double a, b, c;
  97. a = LineSpace(ptStart, ptEnd); //线段长度
  98. b = LineSpace(pt, ptStart); //点到线段顶点1的距离
  99. c = LineSpace(pt, ptEnd); //点到线段顶点2的距离
  100. if (b == 0 || c == 0)
  101. {
  102. distance = 0;
  103. return distance;
  104. }
  105. if (a == 0)
  106. {
  107. distance = b;
  108. return distance;
  109. }
  110. if (c * c >= a * a + b * b)
  111. {
  112. distance = b;
  113. return distance;
  114. }
  115. if (b * b >= a * a + c * c)
  116. {
  117. distance = c;
  118. return distance;
  119. }
  120. double p = (a + b + c) / 2; //半周长
  121. double s = Math.Sqrt(p * (p - a) * (p - b) * (p - c)); // 海伦公式求面积
  122. distance = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
  123. return distance;
  124. }
  125. }
  126. }