namespace Yw.Curve
{
public static class CurvePoint_Extensions
{
///
/// 计算总长度
///
public static double CalcuTotalLength(this List 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;
}
///
/// 获取Y最小的点
///
public static CurvePoint GetPointByMinY(this List ptList)
{
if (ptList == null || ptList.Count < 1)
{
return default;
}
return ptList.OrderBy(x => x.Y).FirstOrDefault();
}
///
/// 获取Y最大的点
///
public static CurvePoint GetPointByMaxY(this List ptList)
{
if (ptList == null || !ptList.Any())
{
return default;
}
return ptList.OrderBy(x => x.Y).LastOrDefault();
}
///
/// 获取Y最小的点索引
///
public static int GetPointIndexByMinY(this List ptList)
{
var pt = GetPointByMinY(ptList);
return ptList.IndexOf(pt);
}
///
/// 获取Y最大的点索引
///
public static int GetPointIndexByMaxY(this List ptList)
{
var pt = GetPointByMaxY(ptList);
return ptList.IndexOf(pt);
}
///
/// 根据X 获取点索引
///
public static int GetPointIndexByX(this List 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;
}
///
/// 获取X方向距离最小的点
///
public static CurvePoint GetClosestPointByX(this List ptList, double x)
{
if (ptList == null || ptList.Count < 1)
{
return default;
}
var pt = ptList.OrderBy(t => Math.Abs(t.X - x)).FirstOrDefault();
return pt;
}
///
/// 获取X方向距离最小的点索引
///
public static int GetClosestPointIndexByX(this List ptList, double x)
{
var pt = GetClosestPointByX(ptList, x);
return ptList.IndexOf(pt);
}
///
/// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点)
///
public static List GetInterPointY(this List ptList, double x)
{
if (ptList == null || ptList.Count < 1)
{
return default;
}
var list = ptList.ToList();
var equalPoints = new List();
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;
}
///
/// ptList 是一个多边形,判断点是否在多边形里
/// 原理是 通过p做一个+X方向的射线, 偶数个交点 就是在外部,奇数个就是在内部
///
public static bool IsInPolygon(this IEnumerable 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;
}
}
}