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