using System.Drawing;
namespace TelpoPush.Fence.Worker.Models.Fence
{
public static class GeofenceHelper
{
public static double CalcDisgreeFromRadius(int radius)
{
double metersPerSecond = 30.0;
double seconds = radius / metersPerSecond;
return seconds / 3600;
}
///
/// 计算点是否在多边形内
///
/// 多边形点集合
/// 要判断的点
/// 是否在多边形内
public static bool IsPolygonContainsPoint(IList polygon, GpsFencePoint pt)
{
return RayCastingAlgorithm.IsWithin(pt, polygon, true);
}
///
/// 判断圆是否和多边形相交
///
/// 多边形点集合
/// 要判断的圆的圆心点
/// 圆半径(单位米)
///
public static bool IsPolygonIntersectCircle(IList polygon, GpsFencePoint ptCenter,int radius)
{
var degree = CalcDisgreeFromRadius(radius);
return CirclePolygonAlgorithm.IsIntersect(ptCenter, degree, polygon);
}
//---yl---新增-- 2022.6.13----
///
/// 判断圆和多边形是否相交
///
/// 圆心坐标
/// 圆半径
/// 多边形各个点坐标
///
public static bool IsCircle2Polygon(Point circle, double radius, IList polygon)
{
bool res = false;
double powRadius = Math.Pow(radius, 2);
//情况1:多边形任一顶点在圆内,则认为相交
foreach (var pt in polygon)
{
if (Math.Pow(circle.X - pt.X, 2) + Math.Pow(circle.Y - pt.Y, 2) < powRadius)
{
res = true;
return res;
//return true;
}
}
//情况2:多边形顶点集的任一有效线段和圆相交(圆心到线段的距离小于半径)
var lines = EnumeratePolygonLines(polygon);
foreach (var seg in lines)
{
if (PointToLine(circle, seg.Item1, seg.Item2) < radius)
{
res = true;
return res;
//return true;
}
//return true;
}
return res;// false;
}
private static IList> EnumeratePolygonLines(IList polygon)
{
var list = new List>();
for (int i = 0; i < polygon.Count - 1; i++)
{
list.Add(new Tuple(polygon[i], polygon[i + 1]));
}
list.Add(new Tuple(polygon[polygon.Count - 1], polygon[0]));
return list;
}
//计算两点之间的距离
private static double LineSpace(Point ptStarts, Point ptEnds)
{
if (ptStarts == ptEnds) return 0;
return Math.Sqrt((ptEnds.X - ptStarts.X) * (ptEnds.X - ptStarts.X) + (ptEnds.Y - ptStarts.Y) * (ptEnds.Y - ptStarts.Y));
}
///
/// 点到线段的距离
///
///
/// 线段顶点1
/// 线段顶点2
///
private static double PointToLine(Point pt, Point ptStart, Point ptEnd)
{
double distance = 0;
double a, b, c;
a = LineSpace(ptStart, ptEnd); //线段长度
b = LineSpace(pt, ptStart); //点到线段顶点1的距离
c = LineSpace(pt, ptEnd); //点到线段顶点2的距离
if (b == 0 || c == 0)
{
distance = 0;
return distance;
}
if (a == 0)
{
distance = b;
return distance;
}
if (c * c >= a * a + b * b)
{
distance = b;
return distance;
}
if (b * b >= a * a + c * c)
{
distance = c;
return distance;
}
double p = (a + b + c) / 2; //半周长
double s = Math.Sqrt(p * (p - a) * (p - b) * (p - c)); // 海伦公式求面积
distance = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
return distance;
}
}
}