using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace IStation.Model { /// /// 曲线拟合辅助类(维护在IStation.Common) /// public class FitCurveHelper { public FitCurveHelper(List points) { _ifitCurvePoint = new TwinRelateCurve3M(points); } public FitCurveHelper(List points, eCurveFitType fitType) { switch (fitType) { case eCurveFitType.ThroughPoint: _ifitCurvePoint = new TwinRelateCurve0(points); break; case eCurveFitType.LinearCurve: _ifitCurvePoint = new TwinRelateCurve1(points); break; case eCurveFitType.ConicCurveB0: _ifitCurvePoint = new TwinRelateCurve2B0(points); break; case eCurveFitType.ConicCurve: _ifitCurvePoint = new TwinRelateCurve2M(points); break; case eCurveFitType.CubicCurve: _ifitCurvePoint = new TwinRelateCurve3M(points); break; case eCurveFitType.FourM: _ifitCurvePoint = new TwinRelateCurve4M(points); break; default: break; } } public FitCurveHelper(List points, int fitPow) { switch (fitPow) { case 0: _ifitCurvePoint = new TwinRelateCurve0(points); break; case 1: _ifitCurvePoint = new TwinRelateCurve1(points); break; case 2: _ifitCurvePoint = new TwinRelateCurve2M(points); break; case 3: _ifitCurvePoint = new TwinRelateCurve3M(points); break; case 4: _ifitCurvePoint = new TwinRelateCurve4M(points); break; default: break; } } public FitCurveHelper(CurveExpress express) { switch (express.FitType) { case eCurveFitType.ThroughPoint: _ifitCurvePoint = new TwinRelateCurve0(express); break; case eCurveFitType.LinearCurve: _ifitCurvePoint = new TwinRelateCurve1(express); break; case eCurveFitType.ConicCurveB0: _ifitCurvePoint = new TwinRelateCurve2B0(express); break; case eCurveFitType.ConicCurve: _ifitCurvePoint = new TwinRelateCurve2M(express); break; case eCurveFitType.CubicCurve: _ifitCurvePoint = new TwinRelateCurve3M(express); break; case eCurveFitType.FourM: _ifitCurvePoint = new TwinRelateCurve4M(express); break; default: break; } } private IFitCurvePoint _ifitCurvePoint = null;//拟合点接口对象 #region 创建曲线表达式 /// /// 创建曲线表达式 /// public static CurveExpress BuildCurveExpress(List points, eCurveFitType fitType) { if (points == null) return default; if (points.Count < 1) return default; switch (fitType) { case eCurveFitType.ThroughPoint: return TwinRelateCurve0.BuildCurveExpress(points); case eCurveFitType.LinearCurve: return TwinRelateCurve1.BuildCurveExpress(points); case eCurveFitType.ConicCurveB0: return TwinRelateCurve2B0.BuildCurveExpress(points); case eCurveFitType.ConicCurve: return TwinRelateCurve2M.BuildCurveExpress(points); case eCurveFitType.CubicCurve: return TwinRelateCurve3M.BuildCurveExpress(points); case eCurveFitType.FourM: return TwinRelateCurve4M.BuildCurveExpress(points); default: return default; } } /// /// 创建曲线表达式 /// public static CurveExpress BuildCurveExpress(List points, int fitPow) { var fitType = CurveExpress.GetFitType(fitPow); return BuildCurveExpress(points, fitType); } #endregion #region 获取零点的Y值 /// /// 获取零点的Y值 /// public static double GetZeroPointY(CurveExpress express) { return express.Index0; } /// /// 获取零点的Y值 2022_03_17_nsx /// public static double GetZeroPointY(List points) { var express = new CurveExpress(points); return express.Index0; } #endregion #region 获取线性插值 /// /// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):不延长 /// public static List GetInterPointY(List points, double x) { if (points == null || points.Count() == 0) return default; var equalPoints = new List(); 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)) {//直线插值 double y; 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); equalPoints.Add(new CurvePoint(x, y)); } } return equalPoints; } /// /// 获得X值的坐标位置,可能有多个点,取第一个点(是线形插值,不是曲线上的点) /// /// /// /// /// public static bool GetInterPointY(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; } /// /// 获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):会延长 /// public static List GetInterPointYByExtend(List points, double x) { if (points == null || points.Count() == 0) return null; var equalPoints = new List(); if (x <= points.First().X) {//暂时不延长,只相同,以后可以继续优化 equalPoints.Add(points.First()); return equalPoints; } if (x >= points.Last().X) { equalPoints.Add(points.Last()); return equalPoints; } 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)) {//直线插值 double y; 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); equalPoints.Add(new CurvePoint(x, y)); } } return equalPoints; } /// /// 获得X值的坐标位置,可能有多个点,取第一个点(是线形插值,不是曲线上的点) /// public static bool GetFirstInterPointY(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; } /// /// 获得X值的坐标位置,可能有多个点,取第一个点(是线形插值,不是曲线上的点) /// public static double GetFirstInterPointY(List points, double x) { if (points == null || points.Count < 1) return default; for (int i = 0; i < points.Count - 1; i++)//少一个点 { if ((x >= points[i].X && x <= points[i + 1].X) || (x <= points[i].X && x >= points[i + 1].X)) {//直线插值 double y; 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 y; } } return default; } //获得X值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):会延长 public static IStation.Model.CurvePointList GetInterPointY_Extend(List points, double x) { if (points == null || points.Count() == 0) return null; IStation.Model.CurvePointList equalPoints = new IStation.Model.CurvePointList(); if (x <= points.First().X) {//暂时不延长,只相同,以后可以继续优化 equalPoints.Add(points.First()); return equalPoints; } if (x >= points.Last().X) { equalPoints.Add(points.Last()); return equalPoints; } 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)) {//直线插值 double y; 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); equalPoints.Add(new IStation.Model.CurvePoint(x, y)); } } return equalPoints; } #endregion #region 获取拟合点 /// /// 获取曲线拟合点Y值 /// public double GetFitPointY(double x) { if (_ifitCurvePoint == null) return default; return _ifitCurvePoint.GetFitPointY(x); } /// /// 获取拟合点列表 /// public List GetFitPoints(int pointNumber) { if (_ifitCurvePoint == null) return default; return _ifitCurvePoint.GetFitPoints(pointNumber); } /// /// 通过区间获取拟合点列表 /// public List GetFitPointsByRange(double x_min, double x_max, int pointNumber) { if (_ifitCurvePoint == null) return default; return _ifitCurvePoint.GetFitPointsByRange(x_min, x_max, pointNumber); } /// /// 获取拟合点Y /// public static double GetFitPointY(List points, int fitPow, double x) { if (points == null || points.Count < fitPow + 1) return default; var helper = new FitCurveHelper(points, fitPow); return helper.GetFitPointY(x); } /*/// /// 获取拟合点Y /// public static double GetFitPointY(List points, eCurveFitType fitType, double x) { if (points == null) return default; var fitPow = CurveExpress.GetFitPow(fitType); if (points.Count < fitPow + 1) return default; var helper = new FitCurveHelper(points, fitType); return helper.GetFitPointY(x); }*/ /// /// 获取 /// /// /// /// /// public static double GetFitPointY(List points, eCurveFitType curveFitType, double x) { if (points == null) return 0; if (curveFitType == eCurveFitType.ThroughPoint) { if (points.Count() < 3) return 0; var bbb = BezierCurveHelper.CreateOpenCurves(points); var ppp = BezierCurveHelper.GetSectPointsByX(bbb, x); if (ppp == null || ppp.Count() == 0) return 0; return ppp.Last().Y; } else if (curveFitType == eCurveFitType.ConicCurve || curveFitType == eCurveFitType.ConicCurveB0) { if (points.Count() < 3) return 0; CurveExpress express = new CurveExpress(points, curveFitType, false); return TwinRelateCurve2M.GetFitPointY(express, x); } else if (curveFitType == eCurveFitType.CubicCurve) { if (points.Count() <= 3) return 0; CurveExpress express = new CurveExpress(points, curveFitType, false); return TwinRelateCurve3M.GetFitPointY(express, x); } else if (curveFitType == eCurveFitType.FourM) { if (points.Count() <= 4) return 0; CurveExpress express = new CurveExpress(points, curveFitType, false); return TwinRelateCurve4M.GetFitPointY(express, x); } else { if (points.Count() <= 3) return 0; CurveExpress express = new CurveExpress(points, curveFitType, false); return TwinRelateCurve3M.GetFitPointY(express, x); } } /// /// 获取拟合点Y /// public static double GetFitPointY(CurveExpress express, double x) { if (express == null) return default; if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPointY(x); } /// /// 获取拟合点Y /// public static double GetFitPointY(string strExpress, double x) { if (string.IsNullOrEmpty(strExpress)) return default; var express = new CurveExpress(strExpress); if (express.IsNull) return default; return GetFitPointY(express, x); } /// /// 获取拟合点 /// public static List GetFitPoints(List points, int pointNumber = 20) { if (points == null) return default; var express = new CurveExpress(points); if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPoints(pointNumber); } /// /// 获取拟合点 /// public static List GetFitPoints(List points, eCurveFitType fitType, int pointNumber = 20) { if (points == null) return default; var express = new CurveExpress(points, fitType); if (express.IsNull) return default; var helper = new FitCurveHelper(points, fitType); return helper.GetFitPoints(pointNumber); } /// /// 获取拟合点 /// public static List GetFitPoints(string strExpress, int point_number = 20) { if (string.IsNullOrEmpty(strExpress)) return default; var express = new CurveExpress(strExpress); if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPoints(point_number); } /// /// 获取拟合点 /// public static List GetFitPoints(CurveExpress express, int pointNumber = 20) { if (express == null) return default; if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPoints(pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByExtend(CurveExpress express, double ratioExtend, int pointNumber) { if (express == null) return default; if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPointsByRange(express.Min, express.Max * ratioExtend, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByExtend2(CurveExpress express, double ratioExtendmin, double ratioExtendmax, int pointNumber) { if (express == null) return default; if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPointsByRange(express.Min * ratioExtendmin, express.Max * ratioExtendmax, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByExtend(List points, eCurveFitType fitType, double ratioExtend, int pointNumber) { if (points == null) return default; var fitPow = CurveExpress.GetFitPow(fitType); if (points.Count < fitPow + 1) return default; var express = new CurveExpress(points, fitType); return GetFitPointsByExtend(express, ratioExtend, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByExtend(List points, double ratioExtend, int pointNumber) { if (points == null) return default; var fitPow = CurveExpress.GetFitPow(eCurveFitType.CubicCurve); if (points.Count < fitPow + 1) return default; if (pointNumber == 0) { pointNumber = points.Count(); } var curveExpress = new CurveExpress(points); return GetFitPointsByExtend(curveExpress, ratioExtend, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByRange(CurveExpress express, double minX, double maxX, int pointNumber = 20) { if (express == null) return default; if (express.IsNull) return default; var helper = new FitCurveHelper(express); return helper.GetFitPointsByRange(minX, maxX, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByRange(List points, double minX, double maxX, int pointNumber = 20) { if (points == null) return default; var express = new CurveExpress(points); if (express.IsNull) return default; return GetFitPointsByRange(express, minX, maxX, pointNumber); } /// /// 获取拟合点 /// public static List GetFitPointsByRange(List points, eCurveFitType fitType, double minX, double maxX, int pointNumber = 20) { if (points == null) return default; var express = new CurveExpress(points, fitType); if (express.IsNull) return default; return GetFitPointsByRange(express, minX, maxX, pointNumber); } #endregion #region 获得X值 //获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):会计算延长部分:而且要求points点按照从小到大排序 public static IStation.Model.CurvePointList GetInterPointExX(List points, double y) { if (points == null) return null; //在范围内 double maxY = (from yyy in points select yyy.Y).Max(); double minY = (from yyy in points select yyy.Y).Min(); if (y > minY && y < maxY) { return GetInterPointX(points, y); } IStation.Model.CurvePointList ptList = new IStation.Model.CurvePointList(); //判断是否在前面的延长部分 double x_start = IStation.Model.CurveLineHelper.GetXbyY(points[0].X, points[0].Y, points[1].X, points[1].Y, y); if (x_start <= points[0].X) { if (x_start > 0 && x_start > points[0].X * 0.9)//放一点余量 ptList.Add(new IStation.Model.CurvePoint(x_start, y)); } //判断是否在后面的延长部分:U型曲线 是前后都有 double x_end = IStation.Model.CurveLineHelper.GetXbyY(points[points.Count - 2].X, points[points.Count - 2].Y, points[points.Count - 1].X, points[points.Count - 1].Y, y); if (x_end >= points[points.Count - 1].X && x_end < points[points.Count - 1].X * 1.1)//放一点余量 { ptList.Add(new IStation.Model.CurvePoint(x_end, y)); } if (ptList.Count == 0) return null; return ptList; } //获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):会计算延长部分:而且要求points点按照从小到大排序 public static IStation.Model.CurvePointList GetInterPointExX(IStation.Model.CurveExpress curve, double y, int interPointNum) { if (curve == null) return null; var points = IStation.Model.FitCurveHelper.GetFitPoints(curve, interPointNum); if (points == null) return null; //在范围内 double maxY = (from yyy in points select yyy.Y).Max(); double minY = (from yyy in points select yyy.Y).Min(); if (y > minY && y < maxY) { return GetInterPointX(points, y); } IStation.Model.CurvePointList ptList = new IStation.Model.CurvePointList(); //判断是否在前面的延长部分 double x_start = IStation.Model.CurveLineHelper.GetXbyY(points[0].X, points[0].Y, points[1].X, points[1].Y, y); if (x_start <= points[0].X) { if (x_start > 0 && x_start > points[0].X * 0.9)//放一点余量 ptList.Add(new IStation.Model.CurvePoint(x_start, y)); } //判断是否在后面的延长部分:U型曲线 是前后都有 double x_end = IStation.Model.CurveLineHelper.GetXbyY(points[points.Count - 2].X, points[points.Count - 2].Y, points[points.Count - 1].X, points[points.Count - 1].Y, y); if (x_end >= points[points.Count - 1].X && x_end < points[points.Count - 1].X * 1.1)//放一点余量 { ptList.Add(new IStation.Model.CurvePoint(x_end, y)); } if (ptList.Count == 0) return null; return ptList; } //获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点):会计算延长部分:而且要求points点按照从小到大排序 public static IStation.Model.CurvePointList GetInterPointExX(IStation.Model.CurveExpress curve, double y, int interPointNum, double extendRatio) { if (curve == null) return null; var points = IStation.Model.FitCurveHelper.GetFitPointsByExtend(curve, extendRatio, interPointNum); if (points == null) return null; //在范围内 double maxY = (from yyy in points select yyy.Y).Max(); double minY = (from yyy in points select yyy.Y).Min(); if (y > minY && y < maxY) { return GetInterPointX(points, y); } IStation.Model.CurvePointList ptList = new IStation.Model.CurvePointList(); //判断是否在前面的延长部分 double x_start = IStation.Model.CurveLineHelper.GetXbyY(points[0].X, points[0].Y, points[1].X, points[1].Y, y); if (x_start <= points[0].X) { if (x_start > 0 && x_start > points[0].X * 0.9)//放一点余量 ptList.Add(new IStation.Model.CurvePoint(x_start, y)); } //判断是否在后面的延长部分:U型曲线 是前后都有 double x_end = IStation.Model.CurveLineHelper.GetXbyY(points[points.Count - 2].X, points[points.Count - 2].Y, points[points.Count - 1].X, points[points.Count - 1].Y, y); if (x_end >= points[points.Count - 1].X && x_end < points[points.Count - 1].X * extendRatio)//放一点余量 { ptList.Add(new IStation.Model.CurvePoint(x_end, y)); } if (ptList.Count == 0) return null; return ptList; } //获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点) public static IStation.Model.CurvePointList GetInterPointX(List points, double y) { if (points == null) return null; IStation.Model.CurvePointList equalPoints = new IStation.Model.CurvePointList(); int num = points.Count(); for (int i = 0; i < num - 1; i++)//少一个点 { if ((y >= points[i].Y && y <= points[i + 1].Y) || (y <= points[i].Y && y >= points[i + 1].Y)) { //直线插值 double x; if (Math.Abs(points[i].Y - points[i + 1].Y) < 0.01) x = (points[i].X + points[i + 1].X) * 0.5; else x = points[i].X + (points[i + 1].X - points[i].X) * (y - points[i].Y) / (points[i + 1].Y - points[i].Y); equalPoints.Add(new IStation.Model.CurvePoint(x, y)); } } return equalPoints; } //获得Y值的坐标位置,可能有多个点(是线形插值,不是曲线上的点) //interPointNum数量越多,精度越高,注意如果点在最高点附近,interPointNum值一定要多 public static IStation.Model.CurvePointList GetInterPointX(IStation.Model.CurveExpress points, double y, int interPointNum = 50) { if (points == null) return null; return GetInterPointX(GetFitPoints(points, interPointNum), y); } //获得Y值的坐标位置,可能有多个点,取第一个点(是线形插值,不是曲线上的点) public static bool GetInterPointX(List points, double y, out double x) { x = 0; if (points == null) return false; int num = points.Count(); for (int i = 0; i < num - 1; i++)//少一个点 { if ((y >= points[i].Y && y <= points[i + 1].Y) || (y <= points[i].Y && y >= points[i + 1].Y)) {//直线插值 if (Math.Abs(points[i].Y - points[i + 1].Y) < 0.01) x = (points[i].X + points[i + 1].X) * 0.5; else x = points[i].X + (points[i + 1].X - points[i].X) * (y - points[i].Y) / (points[i + 1].Y - points[i].Y); return true; } } return true; } #endregion 获得X值 #region 取Y的最大最小值 // public static bool GetMinMaxPointY(List points, out double maxY, out double minY) { if (points == null) { maxY = minY = 0; return false; } var fitPoints = GetFitPoints(points, 50); if (fitPoints == null) { maxY = minY = 0; return false; } maxY = (from x in fitPoints select x.Y).Max(); minY = (from x in fitPoints select x.Y).Min(); return true; } public static bool GetMinMaxPointY(CurveExpress express, out double maxY, out double minY) { if (express == null) { maxY = minY = 0; return false; } var fitPoints = GetFitPoints(express, 50); if (fitPoints == null) { maxY = minY = 0; return false; } maxY = (from x in fitPoints select x.Y).Max(); minY = (from x in fitPoints select x.Y).Min(); return true; } //伸长率 public static bool GetMinMaxPointY_Ratio(CurveExpress express, double extend_min_ratio, double extend_max_ratio, out double maxY, out double minY) { if (express == null) { maxY = minY = 0; return false; } var fitPoints = GetFitPointsByExtend2(express, extend_min_ratio, extend_max_ratio, 50); if (fitPoints == null) { maxY = minY = 0; return false; } maxY = (from x in fitPoints select x.Y).Max(); minY = (from x in fitPoints select x.Y).Min(); return true; } //绝对值 public static bool GetMinMaxPointY_Range(CurveExpress express, double xRangeMin, double xRangeMax, out double maxY, out double minY) { if (express == null) { maxY = minY = 0; return false; } if (xRangeMin >= xRangeMax) { maxY = minY = 0; return false; } var fitPoints = GetFitPointsByRange(express, xRangeMin, xRangeMax, 50); if (fitPoints == null) { maxY = minY = 0; return false; } maxY = (from x in fitPoints select x.Y).Max(); minY = (from x in fitPoints select x.Y).Min(); return true; } //获取Y值最大值的点 public static IStation.Model.CurvePoint GetMaxPoint(CurveExpress express, int pointNumber = 200) { if (express == null) return null; if (express.FitPow <= 0 && express.DefinePoints != null) { return CurvePointList.GetPointOfMaxY(express.DefinePoints); } else if (express.FitType == eCurveFitType.ThroughPoint) { return CurvePointList.GetPointOfMaxY(express.DefinePoints); } else { var points = GetFitPoints(express, pointNumber); return CurvePointList.GetPointOfMaxY(points); } } //绝对值 public static IStation.Model.CurvePoint GetMaxPointByRange(CurveExpress express, double range_min, double range_max, int pointNumber = 200) { if (express == null) return null; var points = GetFitPointsByRange(express, range_min, range_max, pointNumber); return CurvePointList.GetPointOfMaxY(points); } //取points中Y的最大值(一定在points中) public static IStation.Model.CurvePoint GetMaxPointInPoints(List points) { if (points == null) { return new IStation.Model.CurvePoint(0, 0); } double maxPointX = -10000; double maxPointY = -10000; for (int i = 0; i < points.Count(); i++) { if (points[i].Y > maxPointY) { maxPointX = points[i].X; maxPointY = points[i].Y; } } return new IStation.Model.CurvePoint(maxPointX, maxPointY); } #endregion 取Y的最大最小值 //冒泡升序排序 public static void Sort(ref double[] arrX, ref double[] arrY) { int i, j; double tempX, tempY; bool done = false; j = 1; while ((j < arrX.Length) && (!done))//判断长度 { done = true; for (i = 0; i < arrX.Length - j; i++) { if (arrX[i] > arrX[i + 1]) { done = false; tempX = arrX[i]; tempY = arrY[i]; arrX[i] = arrX[i + 1]; arrY[i] = arrY[i + 1];//交换数据 arrX[i + 1] = tempX; arrY[i + 1] = tempY; } } j++; } } //曲线方程字符 public static string GetCurveFunction(CurveExpress express, string xName = "Q") { if (express == null) return null; return express.GetCurveFunction(xName); } public static string GetCurveFunctionRtf(CurveExpress express, string xName = "Q") { if (express == null) return null; //0次方 double index0 = express.Index0; //1次方 double index1 = express.Index1; //2次方 double index2 = express.Index2; //3次方 double index3 = express.Index3; #region 拆分系数 //double firstCoeff = 0; //int firstIndex = 0; //double secondCoeff = 0; //int secondIndex = 0; double thirdCoeff = 0; int thirdIndex = 0; double lastCoeff = 0; int lastIndex = 0; // GetFuncScientificValue(0, index0, ref firstCoeff, ref firstIndex); // GetFuncScientificValue(1, index1, ref secondCoeff, ref secondIndex); GetFuncScientificValue(2, index2, ref thirdCoeff, ref thirdIndex); GetFuncScientificValue(3, index3, ref lastCoeff, ref lastIndex); #endregion StringBuilder sb = new StringBuilder(); #region 设置系数及运算符号 sb.Append(index0.ToString("0.0")); sb.Append(" "); if (index1 > 0) { sb.Append(" + "); sb.Append(index1.ToString("0.00000")); } else { sb.Append(" - "); sb.Append(Math.Abs(index1).ToString("0.00000")); } //sb.Append(@"\'d710\super"); //sb.Append(secondIndex); //sb.Append(@"\nosupersub "); sb.Append(@" \'d7 "); sb.Append(xName); sb.Append(" "); if (thirdCoeff > 0) { sb.Append(" + "); sb.Append(thirdCoeff.ToString("0.0000000000")); } else { sb.Append(" - "); sb.Append(Math.Abs(thirdCoeff).ToString("0.0000000000")); } sb.Append(@" \'d7 10\super "); sb.Append(thirdIndex); sb.Append(@" \nosupersub "); sb.Append(@" \'d7 "); sb.Append(xName); sb.Append(@"\super 2 "); sb.Append(@"\nosupersub "); if (lastCoeff > 0) { sb.Append(" + "); sb.Append(lastCoeff.ToString("0.00000000000000")); } else { sb.Append(" - "); sb.Append(Math.Abs(lastCoeff).ToString("0.00000000000000")); } sb.Append(@" \'d7 10\super "); sb.Append(lastIndex); sb.Append(@" \nosupersub "); sb.Append(@" \'d7 "); sb.Append(xName); sb.Append(@"\super 3 "); sb.Append(@"\nosupersub "); #endregion return sb.ToString(); } private static void GetFuncScientificValue(int FunctionIndex, double FunctionCoeff, ref double signValue, ref int indexValue) { string strList = ""; if (FunctionIndex == 0) { strList = FunctionCoeff.ToString("0.000e+000"); } else if (FunctionIndex == 1) { strList = FunctionCoeff.ToString("0.0000000e+000"); } else if (FunctionIndex == 2) { strList = FunctionCoeff.ToString("#.##########e+000"); } else if (FunctionIndex == 3) { strList = FunctionCoeff.ToString("#.#############e+000"); } string[] st1 = null; st1 = strList.Split('e'); signValue = Convert.ToDouble(st1[0]); indexValue = Convert.ToInt32(st1[1]); } public static string GetCurveFunction(List pointsInfoList, string xName = "Q") { if (pointsInfoList == null) return null; CurveExpress express = new CurveExpress(pointsInfoList); return express.GetCurveFunction(xName); } public static string GetCurveFunctionRtf(List pointsInfoList, string xName = "Q") { if (pointsInfoList == null) return null; CurveExpress express = new CurveExpress(pointsInfoList); return GetCurveFunctionRtf(express, xName); } } }