namespace Yw.Curve
|
{
|
public static class CurvePoint_Extensions
|
{
|
|
/// <summary>
|
/// 计算总长度
|
/// </summary>
|
public static double CalcuTotalLength(this List<CurvePoint> ptList)
|
{
|
if (ptList == null || ptList.Count < 1)
|
{
|
return default;
|
}
|
double length = 0;
|
for (int i = 1; i < ptList.Count; i++)
|
{
|
length += ptList[i].Distance(ptList[i - 1]);
|
}
|
return length;
|
}
|
|
/// <summary>
|
/// 获取Y最小的点
|
/// </summary>
|
public static CurvePoint GetPointByMinY(this List<CurvePoint> ptList)
|
{
|
if (ptList == null || ptList.Count < 1)
|
{
|
return default;
|
}
|
return ptList.OrderBy(x => x.Y).FirstOrDefault();
|
}
|
|
/// <summary>
|
/// 获取Y最大的点
|
/// </summary>
|
public static CurvePoint GetPointByMaxY(this List<CurvePoint> ptList)
|
{
|
if (ptList == null || !ptList.Any())
|
{
|
return default;
|
}
|
return ptList.OrderBy(x => x.Y).LastOrDefault();
|
}
|
|
/// <summary>
|
/// 获取Y最小的点索引
|
/// </summary>
|
public static int GetPointIndexByMinY(this List<CurvePoint> ptList)
|
{
|
var pt = GetPointByMinY(ptList);
|
return ptList.IndexOf(pt);
|
}
|
|
/// <summary>
|
/// 获取Y最大的点索引
|
/// </summary>
|
public static int GetPointIndexByMaxY(this List<CurvePoint> ptList)
|
{
|
var pt = GetPointByMaxY(ptList);
|
return ptList.IndexOf(pt);
|
}
|
|
/// <summary>
|
/// 根据X 获取点索引
|
/// </summary>
|
public static int GetPointIndexByX(this List<CurvePoint> ptList, double x)
|
{
|
if (ptList == null || !ptList.Any())
|
{
|
return -1;
|
}
|
int index = 0;
|
foreach (var pt in ptList)
|
{
|
if (Math.Abs(pt.X - x) < 0.0001)
|
{
|
return index;
|
}
|
index++;
|
}
|
return -1;
|
}
|
|
/// <summary>
|
/// 获取X方向距离最小的点
|
/// </summary>
|
public static CurvePoint GetClosestPointByX(this List<CurvePoint> ptList, double x)
|
{
|
if (ptList == null || ptList.Count < 1)
|
{
|
return default;
|
}
|
var pt = ptList.OrderBy(t => Math.Abs(t.X - x)).FirstOrDefault();
|
return pt;
|
}
|
|
/// <summary>
|
/// 获取X方向距离最小的点索引
|
/// </summary>
|
public static int GetClosestPointIndexByX(this List<CurvePoint> ptList, double x)
|
{
|
var pt = GetClosestPointByX(ptList, x);
|
return ptList.IndexOf(pt);
|
}
|
|
/// <summary>
|
/// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点)
|
/// </summary>
|
public static List<double> GetInterPointY(this List<CurvePoint> ptList, double x)
|
{
|
if (ptList == null || ptList.Count < 1)
|
{
|
return default;
|
}
|
var list = ptList.ToList();
|
var equalPoints = new List<double>();
|
int num = ptList.Count;
|
for (int i = 0; i < num - 1; i++)//少一个点
|
{
|
if ((x >= list[i].X && x <= list[i + 1].X) || (x <= list[i].X && x >= list[i + 1].X))
|
{//直线插值
|
double y;
|
if (Math.Abs(list[i].X - list[i + 1].X) < 0.01)
|
y = (list[i].Y + list[i + 1].Y) * 0.5;
|
else
|
y = list[i].Y + (list[i + 1].Y - list[i].Y) * (x - list[i].X) / (list[i + 1].X - list[i].X);
|
|
equalPoints.Add(y);
|
}
|
}
|
return equalPoints;
|
}
|
|
/// <summary>
|
/// ptList 是一个多边形,判断点是否在多边形里
|
/// 原理是 通过p做一个+X方向的射线, 偶数个交点 就是在外部,奇数个就是在内部
|
/// </summary>
|
public static bool IsInPolygon(this IEnumerable<CurvePoint> ptList, CurvePoint p, bool isClosed = true)
|
{
|
if (ptList == null || ptList.Count() < 1)
|
return default;
|
var list = ptList.ToList();
|
int crossNum = 0;
|
|
for (int i = 0; i < list.Count() - 1; i++)
|
{
|
if (p.IsIntersectLineLeft(list[i], list[i + 1]))
|
{
|
crossNum++;
|
}
|
}
|
|
if (isClosed)
|
{
|
if (p.IsIntersectLineLeft(list[list.Count - 1], list[0]))
|
{
|
crossNum++;
|
}
|
}
|
|
if ((crossNum % 2) == 0)
|
return false;
|
else
|
return true;
|
}
|
|
|
|
}
|
}
|