namespace IStation.Curve { public static class CurvePoint_Extensions { #region Point /// /// 判断是否是0点,用于判断函数是否成功返回 /// public static bool IsZeroPoint(this CurvePoint pt) { if (pt.X < 0.01 && pt.Y < 0.01) return true; else return false; } /// /// 点到线的距离 /// public static double GetDistance(this CurvePoint pt1, List CurvePoints) { if (CurvePoints == null) return 10000; double min_dis = double.MaxValue; double dis = 0; foreach (CurvePoint pt in CurvePoints) { dis = GetDistance(pt1, pt); if (dis < min_dis) min_dis = dis; } return min_dis; } /// /// 两点之间的距离 /// public static double GetDistance(CurvePoint pt1, CurvePoint pt2) { return Math.Sqrt((pt1.X - pt2.X) * (pt1.X - pt2.X) + (pt1.Y - pt2.Y) * (pt1.Y - pt2.Y)); } /// /// 计算总长度 /// 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; } #endregion #region List /// /// 获取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); } /// /// 获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点) /// public static List GetInterPointX(this List ptList, double y) { if (ptList == null || ptList.Count < 1) { return default; } var list = ptList.ToList(); var equalPoints = new List(); int num = list.Count(); for (int i = 0; i < num - 1; i++)//少一个点 { if ((y >= list[i].Y && y <= list[i + 1].Y) || (y <= list[i].Y && y >= list[i + 1].Y)) {//直线插值 double x; if (Math.Abs(list[i].Y - list[i + 1].Y) < 0.01) x = (list[i].X + list[i + 1].X) * 0.5; else x = list[i].X + (list[i + 1].X - list[i].X) * (y - list[i].Y) / (list[i + 1].Y - list[i].Y); equalPoints.Add(x); } } return equalPoints; } /// /// 获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点) /// public static List GetPointsByInterPointX(this List ptList, double y) { if (ptList == null || ptList.Count < 1) { return default; } var list = ptList.ToList(); var equalPoints = new List(); int num = list.Count(); for (int i = 0; i < num - 1; i++)//少一个点 { if ((y >= list[i].Y && y <= list[i + 1].Y) || (y <= list[i].Y && y >= list[i + 1].Y)) {//直线插值 double x; if (Math.Abs(list[i].Y - list[i + 1].Y) < 0.01) x = (list[i].X + list[i + 1].X) * 0.5; else x = list[i].X + (list[i + 1].X - list[i].X) * (y - list[i].Y) / (list[i + 1].Y - list[i].Y); equalPoints.Add(new CurvePoint(x, y)); } } return equalPoints; } /// /// 获得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; } /// /// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点) /// public static List GetPointsByInterPointY(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(new CurvePoint(x, y)); } } return equalPoints; } /// /// 获得X值的坐标位置,可能有多个点,取第一个点(是线形插值,不是曲线上的点) /// public static bool GetInterPointY(this List points, double x, out double y) { y = 0; if (points == null) return false; int num = points.Count(); for (int i = 0; i < num - 1; i++)//少一个点 { if ((x >= points[i].X && x <= points[i + 1].X) || (x <= points[i].X && x >= points[i + 1].X)) {//直线插值 if (Math.Abs(points[i].X - points[i + 1].X) < 0.01) y = (points[i].Y + points[i + 1].Y) * 0.5; else y = points[i].Y + (points[i + 1].Y - points[i].Y) * (x - points[i].X) / (points[i + 1].X - points[i].X); return true; } } return false; } /// /// 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; } /// /// 是否完全相同 /// public static bool IsEqualValueX(this List ptList, List comparerPtList) { if (ptList == null || ptList.Count() == 0) { if (comparerPtList == null || comparerPtList.Count() == 0) { return true; } return false; } if (comparerPtList == null || comparerPtList.Count() == 0) { if (ptList == null || ptList.Count() == 0) { return true; } return false; } if (ptList.Count != comparerPtList.Count) { return false; } for (int i = 0; i < ptList.Count; i++) { if (Math.Abs(ptList[i].X - comparerPtList[i].X) > 0.001) { return false; } } return true; } #region 获取拟合点 /// /// 获取拟合点Y /// public static double GetFitPointY(this List ptList, double x) { if (ptList == null) return default; var express = FitHelper.BuildCurveExpress(ptList, eFitType.CubicCurve); if (express == null) return default; return express.GetFitPointY(x); } /// /// 获取拟合点Y /// public static double GetFitPointY(this List ptList, eFitType fitType, double x) { if (ptList == null) return default; var express = FitHelper.BuildCurveExpress(ptList, fitType); if (express == null) return default; return express.GetFitPointY(x); } /// /// 获取拟合点 /// public static List GetFitPoints(this List ptList, eFitType fitType = eFitType.CubicCurve, int pointNumber = 20) { if (ptList == null) return default; var express = FitHelper.BuildCurveExpress(ptList, fitType); if (express == null) return default; return express.GetFitPoints(pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByExtend(this List ptList, eFitType fitType, double ratioExtend, int pointNumber = 20) { if (ptList == null) return default; var fitPow = FitHelper.GetFitPow(fitType); if (ptList.Count < fitPow + 1) return default; var express = FitHelper.BuildCurveExpress(ptList, fitType); return express.GetFitPointsByExtend(ratioExtend, pointNumber); } #endregion #region 取Y的最大最小值 /// /// 取Y的最大最小值 /// public static bool GetMinMaxPointY(this List ptList, out double maxY, out double minY) { if (ptList == null || !ptList.Any()) { maxY = minY = 0; return false; } var fitPoints = ptList.ToList(); maxY = fitPoints.Max(x => x.Y); minY = fitPoints.Min(x => x.Y); ; return true; } /// /// 取points中Y的最大值(一定在points中) /// public static CurvePoint GetMaxPointY(this List ptList) { if (ptList == null || !ptList.Any()) { return new CurvePoint(0, 0); } return ptList.OrderByDescending(x => x.Y).First(); } #endregion 取Y的最大最小值 #endregion } }