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; } } }